Функция вызова с объяснением области окна (0, function() {})()
Мне любопытно, почему это работает:
var c = {
d: function myFunc() {
console.log(this === window);
}
};
var a = {
b: function() {
console.log(this === a);
(0,c.d)();
c.d();
}
};
a.b();
Выход консоли:
True
True
False
Итак, похоже, что (0, c.d)()
совпадает с c.d.call(window)
, но я не могу найти много причин о том, почему и как это работает. Может кто-нибудь объяснить?
От: Проблемы компилятора Closure
Fiddle: http://jsfiddle.net/wPWb4/2/
Ответы
Ответ 1
Если вы пишете несколько выражений, разделенных запятой (,
), тогда все выражения будут вычисляться, но в итоге вы получите значение последнего выражения:
var x = (1,2,3);
console.log(x); // this will log "3"
Теперь (0,c.d)
- это выражение, которое вернет функцию c.d
, но теперь c
больше не является this
функции. Это означает, что this
укажет на глобальный объект (window
) или останется undefined в строгом режиме. Вы получите тот же эффект с любым из них:
var f = function(x) { return x; };
f(c.d)();
Или просто
var f = c.d;
f();
Ответ 2
Выражение (0, myFunc)
эквивалентно просто myFunc
. Оператор выполняет несколько выражений, оценивает их и возвращает последнее выражение, поэтому (0, myFunc)
возвращает только myFunc
.
Теперь, в вашем методе b
, this
равен a
, потому что b
привязан к a
. Другими словами, b
можно назвать a.b()
. Однако myFunc
не привязан к a
(вы не можете называть myFunc
на a.myFunc()
), поэтому в myFunc
, this
не может быть a
. Фактически, myFunc
вызывается без установки его this
, поэтому он по умолчанию задает глобальный объект window
(или остается undefined в строгом режиме), и поэтому его this
равен window
.
Возможно, вам будет интересно узнать, что такое точка (0, listeners[i])()
, когда они могли просто написать listeners[i]()
. Рассмотрим этот код, который создает массив с двумя элементами, обе функции:
var listeners = [
function () { alert(this); },
function () { alert(this); }
];
Когда вы вызываете listeners[0]()
, то в listeners[0]
функция this
равна listeners
, потому что 0
привязан к listeners
, точно так же, как b
был прикреплен к a
> . Однако, когда вы вызываете функцию с помощью (0, listeners[0])()
, listeners[0]
является "развязанным" из массива listeners
. * Поскольку отключаемая функция больше не привязана ни к чему, ее this
является глобальным объектом window
.
* Как будто вы написали:
var temp = listeners[0];
temp();