Почему "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
- Я надеюсь, что кто-то может помочь с этим - даже мне любопытно узнать это.