#javascript #this
#javascript #это
Вопрос:
У меня есть:
function MyFunc() {
this.myString = "wooooo";
setTimeout(function () {
console.log("printing this.myString", this.myString);
}, 1000);
}
MyFunc();
Если я запускаю этот внутренний узел, я получаю ответ: printing this.myString undefined
(кстати node --version gives v12.16.2
)
Если я попробую это сделать в своих инструментах разработки консоли в браузере Chrome, я получу printing this.myString wooooo
(кстати, у меня chrome 89.0.4389.90)
Кто-нибудь может объяснить мне, почему это отличается в nodejs и js? Почему у него другое поведение?
Спасибо
Комментарии:
1. Это также происходит внутри
node 15.5.1
. Я не думаю, что это проблема V8, поскольку и node, и chrome используют движок v82. Похоже, это связано с тем, что
this
внутри обработчика таймаута ссылается на экземпляр nodejs.org/api/timers.html#timers_class_timeout . Я не смог найти в спецификации ничего о том, чтоthis
должно ссылаться на обработчик тайм-аута, поэтому я предполагаю, что решение принимает среда хоста. Браузеры не устанавливают определенноеthis
значение, и Node, похоже, устанавливает указанное значение.3. На самом деле я пробовал этот урок: youtube.com/watch?v=gigtS_5KOqoamp;t=335s
Ответ №1:
На первый взгляд, обе ссылки на this
должны ссылаться на глобальный объект (при условии нестрогого режима), поскольку обе ссылки встречаются в «обычных» функциях.
Это то, что происходит в браузере.
Однако, если вы действительно регистрируете значение this
, вы можете увидеть, что оно ссылается на экземпляр Timeout
in Node:
Timeout {
_idleTimeout: 1000,
_idlePrev: null,
_idleNext: null,
_idleStart: 21,
_onTimeout: [Function (anonymous)],
_timerArgs: undefined,
_repeat: null,
_destroyed: false,
[Symbol(refed)]: true,
[Symbol(kHasPrimitive)]: false,
[Symbol(asyncId)]: 5,
[Symbol(triggerId)]: 1
}
Очень возможно, что официально не определено, на что this
должно ссылаться в обработчике, поэтому среды могут делать все, что захотят в этом отношении.
Комментарии:
1. Кажется, это определяется как
window
здесь: html.spec.whatwg.org/multipage /. … Хотя никто не говорит, что node должен следовать стандарту DOM.2. @georg: Ах, и в шаге 7.2 также говорится: «Используйте контекстный прокси-сервер метода в качестве обратного вызова этого значения».. .. Я искал неправильные ключевые слова. Но да, я думаю, Node просто предоставляет
setTimeout
реализацию для удобства, а не для следования спецификации DOM.