JavaScript "это" снова указывает на объект Window - PullRequest
6 голосов
/ 02 мая 2010

Я задал вопрос по Javascript, который указывает на объект Window относительно "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 указывает на Window, когда он находится внутри archive.action ???

Ответы [ 2 ]

10 голосов
/ 02 мая 2010

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

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

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

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

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

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

callback.call(this);

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

3 голосов
/ 02 мая 2010

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

например:

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

Просто вызывая функцию как

foo();

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

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

abc.bar();

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

...