javascript снова указывает на объект Window

Я задал вопрос о Javascript this указывает на объект Window относительно "этих" точек к оконному объекту.

вот исходный код

var archive = function(){} 

archive.prototype.action = { 
    test: function(callback){ 
        callback(); 
    }, 
    test2: function(){ 
        console.log(this); 
    } 
} 

var oArchive = new archive(); 
oArchive.action.test(oArchive.action.test2); 

Тим Даун написал: «Но затем эта функция вызывается с использованием callback(), что означает, что она не вызывается как метод, и, следовательно, это глобальный объект».

В чем разница между вызовом функции по ее фактическому имени и callback(), как показано в исходном коде?

Как console.log(this) в test2 указывает на окно, когда оно находится внутри archive.action???


person Moon    schedule 02.05.2010    source источник


Ответы (2)


В JavaScript вы можете вызывать функции, используя 4 различных шаблона вызова:

  • Вызов функции
  • Вызов метода
  • Применить/Позвонить
  • Призыв к строительству

Шаблоны в основном отличаются тем, как инициализируется параметр this.

Когда вы используете oArchive.action.test2(), вы вызываете функцию test2() с шаблоном метода, и в этом случае this будет привязан к объекту action. JavaScript будет использовать шаблон метода всякий раз, когда выражение вызова содержит уточнение (например, выражение с точкой . или выражение [subscript]).

С другой стороны, когда функция не является свойством объекта, она вызывается с использованием шаблона функции. В этом случае параметр this привязан к глобальному объекту, и именно так JavaScript вызывает вашу функцию callback().

Дуглас Крокфорд в своих Книга Good Parts описывает это как ошибку в дизайне языка и предлагает некоторые возможные обходные пути. В вашем случае одним из простых обходных путей будет вызов обратного вызова с использованием call() или apply(), как Тим Даун предложил в предыдущем вопросе:

callback.call(this);

Это работает, потому что шаблон вызова Apply/Call позволяет вам выбрать значение this, которое вам нужно.

person Daniel Vassallo    schedule 02.05.2010
comment
Я думаю, вы также можете использовать oArchive.action.test2.bind(oArchive.action.test) при вызове oArchive.action.test - person Vishal Sakaria; 30.04.2015

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

eg:

var foo = function() {
    alert('hello');
};
var abc = {};
abc.bar = foo;

Просто вызов функции, например

foo();

не дает интерпретатору понятия о том, к какому объекту может быть присоединена функция. Он может быть присоединен к нескольким объектам, может быть переменной и т. д. Таким образом, интерпретатор устанавливает this в глобальный объект.

Но, однако, при вызове функции типа

abc.bar();

интерпретатор знает, что функция прикреплена к объекту abc, поэтому this устанавливается в abc. Даже если и bar, и foo относятся к одному и тому же функциональному объекту, разница в шаблоне вызова приводит к тому, что this ведет себя по-разному.

person z33m    schedule 02.05.2010