但在作为 NodeJS 脚本运行时无效。为什么?"/>
自由函数调用中的 this.property 在我的浏览器控制台和 NodeJS REPL 中有效,但在作为 NodeJS 脚本运行时无效。为什么?
我正在研究常规函数和箭头函数中的“this”关键字,所以按照 Stack Overflow 中的示例,我认为我已经理解了这一点,但有一个细节没有解决。请帮助我。 我不知道为什么,但是当我使用
node myScript.js
测试下面的代码时,结果是 undefined
,而使用 Fiddle 或 Chrome 或 Firefox 时,结果是预期的。
正如我所读到的,因为调用
fo2
函数时没有绑定任何对象,所以它的'this'关键字指的是全局对象,并且应该打印'hi'。使用 node myScript.js
不会发生,但是使用浏览器控制台或 Fiddle 会发生。
我不在函数内部使用 console.log()
以避免返回 undefined
,因为之前在其他 Stack Overflow 答案中已经解释过。
这是代码;
var greeting = 'hi';
const obj = {
greeting: 'hey',
fo() {
const greeting = 'hello';
function fo2 () {
return this.greeting;
};
return fo2();
}
};
console.log(obj.fo()); // 'hi' using browser console and Fiddle, but undefined using `node myScript.js`
回答如下:
这里发生了几件事。
一个是当你运行像
node myScript.js
这样的脚本时,该脚本作为“模块”运行。如果你的 package.json 有 "type": "commonjs"
,或者没有指定 "type"
字段,它作为 CommonJS 模块运行。如果你的 package.json 有 "type": "module"
,它作为 ECMAScript 模块运行。 (相关文档)。
另见REPL 和脚本之间的“这”不同。 TL;DR 是使用 CommonJS 模块,模块中的代码运行时就好像它被包装在以下内容中一样:
var ctx = {};
(function(exports) {
// your code
console.log(this === globalThis); // false
}).call(ctx, ctx);
但是如果你在 REPL 模式下运行 NodeJS(只需在你的系统控制台中运行
node
),那么 this === globalThis
就是 true
,并且在“顶级范围”用 var
声明的变量将被放置在 globalThis
对象,就像它们在浏览器控制台中一样(其中 globalThis
与全局 window
对象同义)。
在您的浏览器控制台中,您会得到“hi”,因为调用您
console.log(this.greeting)
的函数而没有给出特定的 this
,因此它会回落到 globalThis
。但是在 ECMAScript 模块上下文中(例如,NodeJS 脚本与带 "type": "module"
的 package.json 一起运行,或 web <script module>
(模块脚本)),顶层的 this
总是 undefined
.
另一件事是,如果您不指定 strict mode,JavaScript 通常会在默认情况下以 “草率模式” 运行,在这种情况下,尝试读取
undefined
的属性不是错误.严格模式通常是可选的,但在 ECMAScript 模块上下文中,严格模式是默认模式。这就是为什么你在运行 undefined
时得到 node myScript.js
的原因,而如果你做了一些事情来启用严格模式,你实际上会得到一个错误。
以下是在启用严格模式的情况下运行 CommonJS 模块的“幕后”情况(如果您将
"use strict";
放在脚本文件的顶部):
let ctx = {};
(function() {
"use strict";
function a(){
console.log(this.foo);
}
a(); // Uncaught TypeError: Cannot read properties of undefined (reading 'foo')
}).call(ctx);
如果你把
"use script";
放在你的 package.json 中,你会在没有显式使用 "type": "module"
的情况下运行上面的代码得到同样的错误。
更多阅读:https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Operators/this.
更多推荐
自由函数调用中的 this.property 在我的浏览器控制台和 NodeJS REPL 中有效,但在作为 NodeJS 脚本运行时无效。为什么?
发布评论