提问人:andres_rom 提问时间:4/30/2023 最后编辑:starballandres_rom 更新时间:6/3/2023 访问量:108
this.property 在我的浏览器控制台和 NodeJS REPL 中有效,但在作为 NodeJS 脚本运行时则不然。为什么?
this.property in a free function call works in my browser console and NodeJS REPL, but not when running as a NodeJS script. Why?
问:
我正在研究常规函数和箭头函数中的“this”关键字,因此在 Stack Overflow 中的示例之后,我认为我已经理解了这一点,但有一个细节对我来说没有解决。请帮帮我。
我不知道为什么,但是当我使用以下代码测试时,结果是,而使用Fiddle或Chrome或Firefox时,结果是预期的。node myScript.js
undefined
正如我所读到的,由于该函数是在不绑定任何对象的情况下调用的,因此它的“this”关键字指的是全局对象,并且应该打印“hi”。使用浏览器控制台或 Fiddle 不会发生,而是使用。
我不使用函数内部以避免返回,正如之前在其他 Stack Overflow 答案中解释的那样。fo2
node myScript.js
console.log()
undefined
这是代码;
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`
我正在使用 NodeJS 18.12.1。
答:
这里正在发生几件事。
一个是当你运行一个脚本时,该脚本是作为一个“模块”运行的。如果您的package.json有 ,或者没有指定该字段,则它将作为 CommonJS 模块运行。如果您的package.json有 ,它将作为 ECMAScript 模块运行。(相关文档)。也就是说,如果您用作文件扩展名。如果使用 ,NodeJS 会将其视为 CommonJS 模块,如果使用 ,NodeJS 会将其视为 ECMAScript 模块。(相关文档)。node myScript.js
"type": "commonjs"
"type"
"type": "module"
.js
.cjs
.mjs
另请参阅 REPL 和脚本之间的“this”区别。The TL;DR 是使用 CommonJS 模块,模块中的代码就像包装在以下内容中一样运行:
var ctx = {};
(function(exports) {
// your code
console.log(this === globalThis); // false
}).call(ctx, ctx);
但是,如果您在 REPL 模式下运行 NodeJS(只需在系统控制台中运行),则 is 和在“顶级范围”中声明的变量将被放置在对象中,就像它们在浏览器控制台中一样(其中与全局对象同义)。node
this === globalThis
true
var
globalThis
globalThis
window
在浏览器控制台中,您会收到“hi”,因为调用您的函数时没有给出特定的 ,因此它回退到 .但是在 ECMAScript 模块上下文中(例如,NodeJS 脚本使用带有 的 package.json 或 web(模块脚本))运行),顶层始终是 .console.log(this.greeting)
this
globalThis
"type": "module"
<script module>
this
undefined
另一件事是,如果不指定严格模式,JavaScript 通常会默认以“草率模式”运行,其中 never .严格模式通常是选择加入的,但在 ECMAScript 模块上下文中,严格模式是默认模式。这就是为什么你在运行时会遇到错误,如果你做了一些事情来启用严格模式,你实际上会得到一个错误。this
undefined
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);
如果您放入 package.json,则在不显式使用的情况下运行上述代码时会遇到相同的错误。"use strict";
"type": "module"
更多阅读:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this。
评论
fo2()
return fo2()
return this.fo2()