Как выполнять вызов с помощью 'this' внутри цикла forEach

В следующем объекте у меня проблема с использованием ссылки 'this':

function SampleObject(){
    this.addObject = function(object){...}
    ...
    // more code here
    ...
    this.addNewObjects= function(arr){
        arr.forEach( function (obj) {
            this.addObject(new Obj(obj.prop1, obj.prop2));
        });
    }
}

Я предполагаю, что контекст меняется и что 'this' ссылается на итерацию 'obj', а не 'SampleObject'. Однако я решил проблему, используя обычный цикл, я знаю, почему это не работает, и хотел бы знать, есть ли другой способ сделать это.

Ответ 1

Вы можете сохранить это в переменной:

var self = this;
this.addNewObjects = function(arr){
    arr.forEach(function(obj) {
        self.addObject(new Obj(obj.prop1, obj.prop2));
    });
}

или используйте bind:

this.addNewObjects = function(arr) {
    arr.forEach(function(obj) {
        this.addObject(new Obj(obj.prop1, obj.prop2));
    }.bind(this));
}

И обратите внимание, без них this будет объект окна, а не объект. This всегда объект, который был создан с использованием нового ключевого слова или объекта окна, если это обычная функция. В строгом режиме this будет неопределенным в этом случае.

ОБНОВЛЕНИЕ: и с ES6 вы можете использовать функцию стрелки:

this.addNewObjects = function(arr) {
    arr.forEach((obj) => {
        this.addObject(new Obj(obj.prop1, obj.prop2));
    });
}

стрелка функция не имеет свои собственное this и они его получают из внешней области.

UPDATE2: из комментария @viery365 вы можете использовать это как второй аргумент для forEach, и он создаст контекст для функции:

this.addNewObjects = function(arr) {
    arr.forEach(function(obj) {
        this.addObject(new Obj(obj.prop1, obj.prop2));
    }, this);
}

Вы можете прочитать это на странице MDN forEach