Ответ 1
В браузере, работающем в глобальной области, this
всегда window
в вашем примере
var obj1;
var obj2;
function x() {
obj1 = this; // window
}
function y() {
obj2 = this; // window
}
x();
y();
console.log(obj1 === obj2); // window === window = true
console.log(obj1 === this); // window === window = true
Это не то, как он работает в Node. В Node.js все модули (script файлы) выполняются в их собственном closure, в то время как браузеры выполняют все script файлы непосредственно в глобальной области.
Другими словами, практически в любом файле, запущенном в Node, this
будет просто пустым объектом, так как Node обертывает код в анонимную функцию, которая вызывается немедленно, и вы должны получить доступ к глобальный охват в этом контексте с помощью GLOBAL
.
Это также упоминается в документации Globals:
Некоторые из этих объектов фактически не находятся в глобальной области видимости, а в области модуля - это будет отмечено.
Однако при вызове функции без определенного контекста в Node.js, как правило, по умолчанию используется глобальный объект. Тот же GLOBAL
упоминается ранее, в качестве контекста выполнения.
Таким образом, вне функций this
является пустым объектом, поскольку код обернут функцией Node, чтобы создать собственный контекст выполнения для каждого модуля (файл script), а внутри функций - потому что они называются без определенного контекста выполнения, this
- это объект Node GLOBAL
В Node.js вы получите
var obj1;
var obj2;
function x() {
obj1 = this; // GLOBAL
}
function y() {
obj2 = this; // GLOBAL
}
x();
y();
console.log(obj1 === obj2); // GLOBAL === GLOBAL = true
console.log(obj1 === this); // GLOBAL === {} = false
Где последний this
действительно пустой объект, как описано выше
Для полноты, стоит отметить, что в строгом режиме вы получите тот же результат в браузере (true, false
), что и в Node, но это потому, что переменные просто противоположны тем, что они находятся в Node
"use strict"
var obj1;
var obj2;
function x() {
obj1 = this; // undefined
}
function y() {
obj2 = this; // undefined
}
x();
y();
console.log(obj1 === obj2); // undefined === undefined = true
console.log(obj1 === this); // undefined === window = false
Это потому, что значение, переданное как this
функции в строгом режиме, не принудительно превращается в объект (a.k.a. "в штучной упаковке" ).
Для нормальной функции в нестрогом режиме this
всегда является объектом, и он всегда является глобальным объектом, если называется с undefined
или null
этим значением, то есть без конкретной контекст выполнения.
Не только автоматический бокс стоимость исполнения, но обнажение глобального объекта в браузерах является угрозой безопасности, поскольку глобальный объект обеспечивает доступ к функциям, которые "защищают" Условия JavaScript должны быть ограничены.
Таким образом, для функции строгого режима указанный this
не помещается в объект в объект, а если не указано, this
будет undefined
внутри функций, как показано выше, но this
все равно будет окном в глобальном масштабе.
То же самое происходит в строгом режиме в Node.js, где this
внутри функций больше не GLOBAL
, а undefined
, а this
вне функций все равно будет один и тот же пустой объект, и конечный результат будет true, false
, но значение this
будет отличаться в строгом режиме в Node.js.