Почему "this" указывает на "окно" obj при использовании оператора присваивания в iife?

Мне было интересно, почему пример вернет "глобальный", а не "obj2"? И что отличается между '(obj2.say = obj1.say)()' и '(obj2.say)()'? Вот код:

var text = 'global';
var obj1 = { text: 'obj1', say: function () {console.log(this.text)}};
var obj2 = { text: 'obj2'};
(obj2.say = obj1.say)();

3 ответа

Решение

Результатом присваивания является значение, которое было присвоено. Пример:

var foo, bar;
foo = (bar = 42);
console.log(foo); // 42

Следовательно, когда вы делаете (obj2.say = obj1.say)результат присваивания, возвращаемый оператором группировки, является объектом функции в obj1.say,

Все выражение должно быть эквивалентно

var result = obj2.say = obj1.say;
result();

И когда функция называется "нормальным" способом (func()), this относится к глобальному объекту или является undefined в строгом режиме.


(obj2.say)() это действительно особенное. Один оператор группировки не разрешает (внутренние) ссылки на значения. Т.е. результат obj2.sayвнутренне, ссылка, которая описывает доступ члена say на obj2, Оператор группировки, (...)возвращает эту ссылку без изменений, не разрешая ее для фактического объекта функции. Вот почемуthisбудет правильно указывать наobj2, Отказ от оператора группировки имеет тот же эффект.

Это на самом деле вызвано в спецификации:

Этот алгоритм не применяетсяGetValue к результату оценки выражения. Основная мотивация для этого заключается в том, чтобы такие операторы, как delete а также typeof может применяться к выражениям в скобках.

Поскольку значение (obj2.say = obj1.say) является простым объектом Function, а obj2.say() является вызовом метода с obj2.

(obj2.say)() просто позвоню say функция от obj2,

(obj2.say = obj1.say)() назначит obj1.say в obj2.say а потом позвони.

Я не уверен насчет this.text - Я надеюсь, что кто-то может помочь с этим - даже мне любопытно узнать это.

Другие вопросы по тегам