Измените его на:
this.colors.forEach((x) => this.printColor(x));
Причина, по которой исходный код не работает должным образом, связана с тем, как scope работает в javascript, особенно с тем, как значение this
ограничено.
Главное, что нужно понять, это то, что (в общем), когда вы вызываете функцию, this
имеет значение , установленное для объекта, для которого был вызван метод .
wookie.eatBanana(); // inside the eatBanana method, this === wookie
Но если вы вызываете метод отдельно от объекта, this
в конечном итоге становится undefined
:
const detachedFn = wookie.eatBanana;
// same function, but now this === undefined
detachedFn();
И что вы делаете, когда проходите this.printColor
в forEach
передает саму функцию , которая в конечном итоге вызывается без привязки к вашему объекту:
const detachedFn = this.printColor;
this.colors.forEach((x) => detachedFn(x)); // this === undefined inside detachedFn, because it's invoked standalone
Внутри реализации forEach
она просто вызывает Функция была дана. Фактически:
// pseudocode
function forEach(fn) {
fn(); // no reference to your class instance; fn is just a regular function.
}
Определение новой функции, которая вызывает this.printColor()
, сохраняет область:
this.colors.forEach((x) => this.printColor(x));
function forEach(fn) {
fn(); // inside this function your method is called *on your object*, preserving the 'this' binding.
}
Функции стрелок Автоматическое связывание с родительской областью :
Функция стрелки не имеет этого. Используется значение this лексической области видимости; Функции стрелок следуют нормальным правилам поиска переменных. Таким образом, при поиске этого, которого нет в текущей области видимости, функция стрелки в конечном итоге находит его из входящей в него области.
Функция автоматической привязки функции стрелки также пригодится для решения этих проблем, если вы объявите методы как функции стрелок для начала. (Это экспериментально и может потребоваться плагин свойств класса babel .) bind :
// make a copy of printColor that's explicitly bound to 'this'.
const explicitlyBoundFn = this.printColor.bind(this);
// works
this.colors.forEach(explicitlyBoundFn);
Вы также можете выполнить sh это через вызов или применить , которые оба позволяют передавать в область (хотя в этом случае нет причин делать это).
// no reason to do this, but it works.
const detachedFn = this.printColor;
this.colors.forEach((x) => detachedFn.call(this, x));
Надеюсь, это поможет. Рад обновить его, если что-то требует разъяснений.