2011-12-29 2 views
18

Может ли кто-нибудь объяснить мне, почему A является истинным, а B является ложным? Я бы ожидал, что B тоже будет правдой.это значение в анонимной функции JavaScript

function MyObject() { 

}; 

MyObject.prototype.test = function() { 
    console.log("A", this instanceof MyObject); 
    (function() { 
     console.log("B", this instanceof MyObject); 
    }()); 
} 

new MyObject().test(); 
+5

Добро пожаловать в функциональную область JavaScript. – zzzzBov

+1

@zzzzBov: Это не закрытие. – SLaks

+0

Возможно, вы захотите использовать дополнительную пару парнеров для улучшения читаемости: '(new MyObject()) .test()' –

ответ

15

this является особенным.Он ссылается на объект, который функция вызывается от имени (чаще всего через точечный синтаксис).

Так, в случае A функция вызывается от имени нового объекта MyObject. B находится в другой функции, которая явно не вызывается от имени любого объекта, поэтому this по умолчанию использует глобальный объект (window).

Иными словами, this изменяется в зависимости от того, как функция называется, а не где и как она определена. Тот факт, что вы используете анонимную функцию (определенную внутри другой функции), является случайным и не влияет на значение this.

+4

Ваше утверждение« 'this' изменяется в зависимости от того, как функция * называется *, а не где или как это определено ", может вводить в заблуждение.Фактически, 'this' является просто владельцем вызываемой функции, и он сам по себе всегда либо явно определен, либо по умолчанию является глобальным объектом. 'myVar.doSomething = doSomething;' определяет функцию 'myVar.doSomething' как' doSomething', где 'this' всегда будет ссылаться на' myVar' при вызове 'myVar.doSomething()', независимо от того, где 'myVar.doSomething() 'вызывается из. Ваше заявление может предложить другое. – Navigateur

3

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

Вы можете написать (function() { ... }).call(this), чтобы явным образом назовите его this.

+0

Ну, я принимаю строгий режим, поэтому ... ':)' –

+0

@ ŠimeVidas: Что? – SLaks

+0

... поэтому 'this'' undefined'. –

26

Внутри вашей анонимной функции this является глобальным объектом.

Внутри test это экземпляр MyObject, на котором был вызван метод.


Всякий раз, когда вы вызываете функцию, как это:

somceFunction(); // called function invocation 

this является всегда глобальный объект, или undefined в строгом режиме (если someFunction не был создан с bind** - смотрите ниже)

Всякий раз, когда вы вызываете функцию, подобную этой

foo.someMethod(); //called method invocation 

this установлен в foo


** ECMAScript5 определяет bind функцию, которая позволяет создать функцию, которая имеет предварительно установленное значение для this

Так это

var obj = { a: 12 }; 
    var someFunction = (function() { alert(this.a); }).bind(obj); 
    someFunction(); 

Причин someFucntion быть вызваны с this равным obj и предупреждением 12. Я поднимаю это лишь отметить, что это потенциальное исключение из этого правила я упоминал о функциях, вызываемых в

someFunction(); 

всегда имеющая this равной глобальный объект (или undefined в строгом режиме)

+0

Строка '(function() {alert (this.a);}). Bind (obj)' именно то, что я искал, - связывание контекста с анонимной функцией. Работает отлично, +1 –

+0

вы также можете установить 'this' с помощью' func.call (this, arg1, arg2 ..) ' – Omu

6

в анонимной функции, this связывается с глобальным объектом (window в среде браузера).

Существуют различные способы доступа к экземпляру:

var self = this; 
(function() { 
    console.log("B", self instanceof MyObject); 
}()); 

или

(function() { 
    console.log("B", this instanceof MyObject); 
}).call(this); 
Смежные вопросы