NodeJS 中的“全局”对象是啥
Posted
技术标签:
【中文标题】NodeJS 中的“全局”对象是啥【英文标题】:What is the 'global' object in NodeJSNodeJS 中的“全局”对象是什么 【发布时间】:2017-09-23 11:14:40 【问题描述】:我刚刚在 NodeJS 环境中看到了 this
关键字的奇怪行为。我用代码列出它们。我已经使用 NodeJS v6.x
运行此代码,并使用单个 javascript
文件。
在使用如下一行代码进行测试时,无论是否使用'use strict'
语句,this 都指向一个空对象。
console.log(this)
但是,当我在自执行函数中运行语句时,
(function()
console.log(this);
());
它正在打印一个非常大的对象。在我看来,NodeJS
环境创建的全局执行上下文对象。
在使用'use strict'
语句执行上述函数时,预计它会打印undefined
(function()
'use strict';
console.log(this);
());
但是,在使用浏览器时(我只使用Chrome
进行了测试),前三个示例产生了window
对象,最后一个示例产生了undefined
。
浏览器的行为是可以理解的。但是,在NodeJS
的情况下,它不会创建执行上下文,直到我包装在一个函数中?
所以,NodeJS
中的大部分代码都以空的 global object
?
【问题讨论】:
看看:***.com/questions/22770299/… 【参考方案1】:虽然在浏览器中全局范围是window
对象,但在 nodeJS 中,模块的全局范围是模块本身,因此当您在 nodeJS 模块的全局范围内定义变量时,它将是本地的模块。
您可以在 NodeJS documentation 中阅读更多相关信息:
全球
<Object> The global namespace object.
在浏览器中,***作用域是全局作用域。这意味着 在浏览器中,如果你在全局范围 var 中,某些东西会定义一个 全局变量。在 Node.js 中这是不同的。***范围是 不是全局范围; Node.js 模块中的 var 内容将是 该模块的本地。
在你写代码的时候:
console.log(this)
在一个空的 js 文件(模块)中,它将打印一个空对象
引用您的空模块。
console.log(this);
在自调用函数中,this
将指向全局 nodeJS 范围对象,该对象包含所有 NodeJS 常用属性和方法,例如require()
、module
、exports
、console
...李>
console.log(this)
和 strict mode 在自调用函数中,它将打印 undefined
,因为自调用函数在 Strict mode 中没有默认的本地范围对象。
【讨论】:
"... 将打印一个空对象 引用您的空模块。"这有点误导。下面的 Willem van der Veen 给出了更好的答案。 this 的值 不是指“模块”,而是指当前的“module.exports”-object。模块(-object)本身不是“空的”,因为它具有属性“exports”,其值是一个没有本地属性的对象,有时称为“空对象”。但即使是这样一个“空”对象 也确实不是“空”的,因为它确实具有继承的属性,例如它的方法“toString()”。 @PanuLogic 声明完全是logic
,如果你想成为逻辑并且不误导,这是事实,你所说的属性总是被所有人继承对象,不值得一提,顺便说一句,它是 Docs 规范。 我们在这里讨论的是 this
或 nodejs 中的全局对象,而不是 Javascript object
定义,所以我们应该关注这一点 :)【参考方案2】:
节点模块中this
的值:
this
in NodeJS global scope 是当前的 module.exports 对象,而不是全局对象。这与全局范围是全局window
对象的浏览器不同。考虑以下在 Node 中执行的代码:
console.log(this); // logs
module.exports.foo = 5;
console.log(this); // log foo:5
首先我们记录一个空对象,因为此模块中的module.exports
中没有值。然后我们将foo
放在module.exports
对象上,当我们再次记录this
时,我们可以看到它现在记录了更新的module.exports
对象。
我们如何访问global
对象:
我们可以使用global
关键字访问节点中的global
对象:
console.log(global);
global
对象公开了有关环境的各种有用属性。这也是setImmediate
和clearTimeout
函数所在的地方。
【讨论】:
这是我真正需要的答案。 这是我想说的最准确的答案,尽管答案的标题与最初提出的问题(“节点模块中的 this 的值......”)略有不同。仍然最有助于理解这一切,强调“this”和“全局对象”不仅在 Node.js 中,而且在一般 JavaScript 中都是两个不同的东西 如果你想引用在任何上下文中工作的全局对象,你可以从一个直接调用的函数中读取this
。 const global = (function() return this)();
。这在浏览器中计算为window
,在服务工作者中计算为self
,在nodejs 中计算为global
。【参考方案3】:
非常有趣:
var JSON = require('circular-json');
console.log('1) ' + JSON.stringify(this, null, 2));
(function()
console.log('2) ' + JSON.stringify(this, null, 2));
());
(function()
'use strict';
console.log('3) ' + JSON.stringify(this, null, 2));
());
将产生:
1)
2)
"global": "~",
"process":
"title": "node",
"version": "v6.9.1",
"moduleLoadList": [
"Binding contextify",
"Binding natives",
"NativeModule events",
"NativeModule util",
"Binding uv",
"NativeModule buffer",
"Binding buffer",
"Binding util",
"NativeModule internal/util",
"NativeModule timers",
"Binding timer_wrap",
"NativeModule internal/linkedlist",
"NativeModule assert",
"NativeModule internal/process",
"Binding config",
"NativeModule internal/process/warning",
"NativeModule internal/process/next_tick",
"NativeModule internal/process/promises",
"NativeModule internal/process/stdio",
"Binding constants",
"NativeModule path",
"NativeModule module",
"NativeModule internal/module",
"NativeModule vm",
"NativeModule fs",
"Binding fs",
"NativeModule stream",
"NativeModule _stream_readable",
"NativeModule internal/streams/BufferList",
"NativeModule _stream_writable",
"NativeModule _stream_duplex",
"NativeModule _stream_transform",
"NativeModule _stream_passthrough",
"Binding fs_event_wrap",
"NativeModule console",
"Binding tty_wrap",
"NativeModule tty",
"NativeModule net",
"NativeModule internal/net",
"Binding cares_wrap",
"Binding tcp_wrap",
"Binding pipe_wrap",
"Binding stream_wrap",
"Binding signal_wrap"
],
"versions":
"http_parser": "2.7.0",
"node": "6.9.1",
"v8": "5.1.281.84",
"uv": "1.9.1",
"zlib": "1.2.8",
"ares": "1.10.1-DEV",
"icu": "57.1",
"modules": "48",
"openssl": "1.0.2j"
,
"arch": "x64",
"platform": "linux",
"release":
"name": "node",
"lts": "Boron",
"sourceUrl": "https://nodejs.org/download/release/v6.9.1/node-v6.9.1.tar.gz",
"headersUrl": "https://nodejs.org/download/release/v6.9.1/node-v6.9.1-headers.tar.gz"
,
"argv": [
"/usr/local/bin/node",
"/home/froth/freelancer-projects/thistest.js"
],
"execArgv": [],
"env":
"NVM_DIR": "/home/froth/.nvm",
"LD_LIBRARY_PATH": "/opt/opencascade/lib",
"CSF_UnitsDefinition": "/opt/opencascade/src/UnitsAPI/Units.dat",
"CSF_GraphicShr": "/opt/opencascade/lib/libTKOpenGl.so",
"CSF_EXCEPTION_PROMPT": "1",
"LANG": "de_DE.UTF-8",
"PROFILEHOME": "",
"DISPLAY": ":0",
"SHELL_SESSION_ID": "09b6f0f3b1d94c5f8aba3f8022075677",
"NODE_PATH": "/usr/lib/node_modules",
"COLORTERM": "truecolor",
"NVM_CD_FLAGS": "",
"MOZ_PLUGIN_PATH": "/usr/lib/mozilla/plugins",
"CSF_IGESDefaults": "/opt/opencascade/src/XSTEPResource",
"CSF_XCAFDefaults": "/opt/opencascade/src/StdResource",
"XDG_VTNR": "1",
"PAM_KWALLET5_LOGIN": "/tmp/kwallet5_froth.socket",
"CSF_STEPDefaults": "/opt/opencascade/src/XSTEPResource",
"XDG_SESSION_ID": "c2",
"CSF_XSMessage": "/opt/opencascade/src/XSMessage",
"USER": "froth",
"DESKTOP_SESSION": "/usr/share/xsessions/awesome",
"GTK2_RC_FILES": "/home/froth/.gtkrc-2.0",
"PWD": "/home/froth/freelancer-projects",
"HOME": "/home/froth",
"XDG_SESSION_TYPE": "x11",
"CSF_PluginDefaults": "/opt/opencascade/src/StdResource",
"XDG_DATA_DIRS": "/usr/local/share/:/usr/share/:/var/lib/snapd/desktop",
"NVM_IOJS_ORG_MIRROR": "https://iojs.org/dist",
"KONSOLE_DBUS_SESSION": "/Sessions/1",
"XDG_SESSION_DESKTOP": "",
"CSF_StandardDefaults": "/opt/opencascade/src/StdResource",
"CSF_StandardLiteDefaults": "/opt/opencascade/src/StdResource",
"MMGT_CLEAR": "1",
"KONSOLE_DBUS_WINDOW": "/Windows/1",
"CSF_UnitsLexicon": "/opt/opencascade/src/UnitsAPI/Lexi_Expr.dat",
"GTK_MODULES": "canberra-gtk-module",
"MAIL": "/var/spool/mail/froth",
"NVM_RC_VERSION": "",
"CSF_XmlOcafResource": "/opt/opencascade/src/XmlOcafResource",
"TERM": "xterm-256color",
"SHELL": "/bin/bash",
"KONSOLE_DBUS_SERVICE": ":1.23",
"XDG_SESSION_CLASS": "user",
"XDG_SEAT_PATH": "/org/freedesktop/DisplayManager/Seat0",
"XDG_CURRENT_DESKTOP": "",
"QT_LINUX_ACCESSIBILITY_ALWAYS_ON": "1",
"KONSOLE_PROFILE_NAME": "Shell",
"CASROOT": "/opt/opencascade",
"NVM_NODEJS_ORG_MIRROR": "https://nodejs.org/dist",
"COLORFGBG": "15;0",
"XDG_SEAT": "seat0",
"SHLVL": "2",
"LANGUAGE": "",
"WINDOWID": "29360134",
"LOGNAME": "froth",
"DBUS_SESSION_BUS_ADDRESS": "unix:path=/run/user/1000/bus",
"XDG_RUNTIME_DIR": "/run/user/1000",
"CSF_MDTVTexturesDirectory": "/opt/opencascade/src/Textures",
"XAUTHORITY": "/home/froth/.Xauthority",
"XDG_SESSION_PATH": "/org/freedesktop/DisplayManager/Session1",
"PATH": "/home/froth/.gem/ruby/2.3.0/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/snap/bin:/usr/lib/jvm/default/bin:/opt/opencascade/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl",
"CSF_LANGUAGE": "us",
"CSF_SHMessage": "/opt/opencascade/src/SHMessage",
"OLDPWD": "/home/froth",
"_": "/usr/local/bin/node"
,
"pid": 4658,
"features":
"debug": false,
"uv": true,
"ipv6": true,
"tls_npn": true,
"tls_alpn": true,
"tls_sni": true,
"tls_ocsp": true,
"tls": true
,
"_needImmediateCallback": false,
"execPath": "/usr/local/bin/node",
"debugPort": 5858,
"_events":
"SIGWINCH": [
null,
null
]
,
"_eventsCount": 4,
"domain": null,
"_exiting": false,
"config":
"target_defaults":
"cflags": [],
"default_configuration": "Release",
"defines": [],
"include_dirs": [],
"libraries": []
,
"variables":
"asan": 0,
"debug_devtools": "node",
"force_dynamic_crt": 0,
"gas_version": "2.23",
"host_arch": "x64",
"icu_data_file": "icudt57l.dat",
"icu_data_in": "../../deps/icu-small/source/data/in/icudt57l.dat",
"icu_endianness": "l",
"icu_gyp_path": "tools/icu/icu-generic.gyp",
"icu_locales": "en,root",
"icu_path": "deps/icu-small",
"icu_small": true,
"icu_ver_major": "57",
"node_byteorder": "little",
"node_enable_d8": false,
"node_enable_v8_vtunejit": false,
"node_install_npm": true,
"node_module_version": 48,
"node_no_browser_globals": false,
"node_prefix": "/",
"node_release_urlbase": "https://nodejs.org/download/release/",
"node_shared": false,
"node_shared_cares": false,
"node_shared_http_parser": false,
"node_shared_libuv": false,
"node_shared_openssl": false,
"node_shared_zlib": false,
"node_tag": "",
"node_use_bundled_v8": true,
"node_use_dtrace": false,
"node_use_etw": false,
"node_use_lttng": false,
"node_use_openssl": true,
"node_use_perfctr": false,
"node_use_v8_platform": true,
"openssl_fips": "",
"openssl_no_asm": 0,
"shlib_suffix": "so.48",
"target_arch": "x64",
"uv_parent_path": "/deps/uv/",
"uv_use_dtrace": false,
"v8_enable_gdbjit": 0,
"v8_enable_i18n_support": 1,
"v8_inspector": true,
"v8_no_strict_aliasing": 1,
"v8_optimized_debug": 0,
"v8_random_seed": 0,
"v8_use_snapshot": true,
"want_separate_host_toolset": 0
,
"stdout":
"connecting": false,
"_hadError": false,
"_handle":
"bytesRead": 0,
"_externalStream": ,
"fd": 9,
"writeQueueSize": 0,
"owner": "~process~stdout"
,
"_parent": null,
"_host": null,
"_readableState":
"objectMode": false,
"highWaterMark": 16384,
"buffer":
"head": null,
"tail": null,
"length": 0
,
"length": 0,
"pipes": null,
"pipesCount": 0,
"flowing": null,
"ended": false,
"endEmitted": false,
"reading": false,
"sync": true,
"needReadable": false,
"emittedReadable": false,
"readableListening": false,
"resumeScheduled": false,
"defaultEncoding": "utf8",
"ranOut": false,
"awaitDrain": 0,
"readingMore": false,
"decoder": null,
"encoding": null
,
"readable": false,
"domain": null,
"_events": ,
"_eventsCount": 3,
"_writableState":
"objectMode": false,
"highWaterMark": 16384,
"needDrain": false,
"ending": false,
"ended": false,
"finished": false,
"decodeStrings": false,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": false,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 1,
"prefinished": false,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree":
"next": null,
"entry": null
,
"writable": true,
"allowHalfOpen": false,
"destroyed": false,
"_bytesDispatched": 6,
"_sockname": null,
"_writev": null,
"_pendingData": null,
"_pendingEncoding": "",
"server": null,
"_server": null,
"columns": 84,
"rows": 84,
"_type": "tty",
"fd": 1,
"_isStdio": true
,
"stderr":
"connecting": false,
"_hadError": false,
"_handle":
"bytesRead": 0,
"_externalStream": ,
"fd": 11,
"writeQueueSize": 0,
"owner": "~process~stderr"
,
"_parent": null,
"_host": null,
"_readableState":
"objectMode": false,
"highWaterMark": 16384,
"buffer":
"head": null,
"tail": null,
"length": 0
,
"length": 0,
"pipes": null,
"pipesCount": 0,
"flowing": null,
"ended": false,
"endEmitted": false,
"reading": false,
"sync": true,
"needReadable": false,
"emittedReadable": false,
"readableListening": false,
"resumeScheduled": false,
"defaultEncoding": "utf8",
"ranOut": false,
"awaitDrain": 0,
"readingMore": false,
"decoder": null,
"encoding": null
,
"readable": false,
"domain": null,
"_events": ,
"_eventsCount": 3,
"_writableState":
"objectMode": false,
"highWaterMark": 16384,
"needDrain": false,
"ending": false,
"ended": false,
"finished": false,
"decodeStrings": false,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": true,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 0,
"prefinished": false,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree":
"next": null,
"entry": null
,
"writable": true,
"allowHalfOpen": false,
"destroyed": false,
"_bytesDispatched": 0,
"_sockname": null,
"_writev": null,
"_pendingData": null,
"_pendingEncoding": "",
"server": null,
"_server": null,
"columns": 84,
"rows": 84,
"_type": "tty",
"fd": 2,
"_isStdio": true
,
"stdin":
"connecting": false,
"_hadError": false,
"_handle":
"bytesRead": 0,
"_externalStream": ,
"fd": 12,
"writeQueueSize": 0,
"owner": "~process~stdin",
"reading": false
,
"_parent": null,
"_host": null,
"_readableState":
"objectMode": false,
"highWaterMark": 0,
"buffer":
"head": null,
"tail": null,
"length": 0
,
"length": 0,
"pipes": null,
"pipesCount": 0,
"flowing": null,
"ended": false,
"endEmitted": false,
"reading": false,
"sync": false,
"needReadable": true,
"emittedReadable": false,
"readableListening": false,
"resumeScheduled": false,
"defaultEncoding": "utf8",
"ranOut": false,
"awaitDrain": 0,
"readingMore": false,
"decoder": null,
"encoding": null
,
"readable": true,
"domain": null,
"_events": ,
"_eventsCount": 4,
"_writableState":
"objectMode": false,
"highWaterMark": 0,
"needDrain": false,
"ending": false,
"ended": false,
"finished": false,
"decodeStrings": false,
"defaultEncoding": "utf8",
"length": 0,
"writing": false,
"corked": 0,
"sync": true,
"bufferProcessing": false,
"writecb": null,
"writelen": 0,
"bufferedRequest": null,
"lastBufferedRequest": null,
"pendingcb": 0,
"prefinished": false,
"errorEmitted": false,
"bufferedRequestCount": 0,
"corkedRequestsFree":
"next": null,
"entry": null
,
"writable": false,
"allowHalfOpen": false,
"destroyed": false,
"_bytesDispatched": 0,
"_sockname": null,
"_writev": null,
"_pendingData": null,
"_pendingEncoding": "",
"server": null,
"_server": null,
"isRaw": false,
"isTTY": true,
"fd": 0
,
"argv0": "node",
"mainModule":
"id": ".",
"exports": ,
"parent": null,
"filename": "/home/froth/freelancer-projects/thistest.js",
"loaded": false,
"children": [
"id": "/home/froth/freelancer-projects/node_modules/circular-json/build/circular-json.node.js",
"exports": ,
"parent": "~process~mainModule",
"filename": "/home/froth/freelancer-projects/node_modules/circular-json/build/circular-json.node.js",
"loaded": true,
"children": [],
"paths": [
"/home/froth/freelancer-projects/node_modules/circular-json/build/node_modules",
"/home/froth/freelancer-projects/node_modules/circular-json/node_modules",
"/home/froth/freelancer-projects/node_modules",
"/home/froth/node_modules",
"/home/node_modules",
"/node_modules"
]
],
"paths": [
"/home/froth/freelancer-projects/node_modules",
"/home/froth/node_modules",
"/home/node_modules",
"/node_modules"
]
,
"console":
3) undefined
在3)
this 中是undefined,因为它在严格模式下没有自动装箱到对象。这意味着在此上下文中没有根对象。如果您不使用严格模式,那么您的代码将被父范围装箱。正如您在输出中看到的,在 nodejs 中有很多关于节点内部内容的信息。
在1)
中,输出是一个空对象,因为在节点模块的***代码中,这相当于 module.exports 并且在本例中 module.exports 是空的。
【讨论】:
【参考方案4】:在节点环境中的全局上下文中以documentation 开头
在浏览器中,***作用域是全局作用域。这意味着在浏览器中,如果您处于全局范围 var 中,则某些内容将定义一个全局变量。在 Node.JS 中这是不同的。***范围不是全局范围; Node.JS 模块中的 var 内容将是该模块的本地内容。
每个 JS 文件都被视为一个模块。 Node 自动将 JS 文件的代码封装在一个 self IIFE 中,并以 exports, require, module, __filename, __dirname
作为函数的参数。
下面是使用node-debug
的执行上下文截图
如果你运行下面的代码,打印出true
,这意味着this
指的是node.js中的exports
。最好在 answer 中解释。
console.log(this === exports);
这意味着在执行时,代码被包装在 Node.js 中,如下所示,假设使用 wrapper function context or IIFE 技术将您的代码与全局上下文分开。
var context = (function (exports, require, module, __filename, __dirname)
console.log(this) //This is my code
);
/** hypothetical module wrapper code **/
var module = exports:;
context.apply(module.exports, [module.exports, require, module, "FILE_NAME", "DIR_NAME"]);
对下一点的回答完全参考这个documentation:
与其他语言相比,函数的
this
关键字在 JavaScript 中的行为略有不同。严格模式和非严格模式也有一些区别。
所以当你执行这段代码时
(function()
console.log(this);
());
打印global
对象并在use strict
模式下打印undefined
记住:
在浏览器中,函数不像 Node.JS 中那样被 IIFE wrapper function 上下文包裹,而是直接在 window
对象上执行。因此,Node.JS 和浏览器的调用上下文会有所不同。
另请阅读this 文章。
【讨论】:
【参考方案5】:global
是对 NodeJS 中真正的全局范围对象的引用,有点像在浏览器 JS 环境中使用 window
。
global.studentName = 'Kyle'
console.log(`Hello, $ global.studentName !`)
// Hello, Kyle!
console.log(`Hello, $ studentName !`)
// Hello, Kyle!
【讨论】:
【参考方案6】:我已经写了一个全面的答案,涵盖了this
在不同情况下的价值。在需要的地方添加解释作为代码 cmets。
let this_in_objects =
propA: "let's figure THIS out!",
/*
* Object property set to a standard function.
* */
propB: function ()
return this.propA;
// Returns the value of this_in_objects.propA as expected.
,
/*
* Object property set to an arrow function (Introduced in ES6).
* */
propC: () =>
return this.propA;
// Should return 'undefined'
// In this case, 'this' refers to the surrounding scope, which could be one of the following :
// - 'module.exports' if the code is inside a nodejs module.
// - 'window' if the code is executed in a browser, or 'undefined' if running in a terminal due to the lack of 'window' global variable.
,
/*
* Object property set to a standard function that returns an arrow function.
* */
propD: function ()
let newArrowFunction = () =>
return this.propA;
// Returns the value of this_in_objects.propA.
// The first functions declaration binds 'this' to the current object
// then the second function scope is now the 'this' of the first function.
return newArrowFunction;
,
/*
* Object property set another object with 2 properties, one of which returns a standard function.
* */
propE:
propE_1: "value of propE.propE_1",
propE_2: function ()
return this.propE_1;
// In this case, 'this' refers to the surrounding scope, which is the parent object 'propE'
,
/*
* Object property set another object with 2 properties, one of which returns an arrow function.
* */
propF:
propF_1: "value of propF.propF_1",
propF_2: () =>
return this.propF_1;
// Should return 'undefined'
// There no change in the binding of 'this', so
// In this case, 'this' refers to the surrounding scope, which could be one of the following :
// - 'module.exports' if the code is inside a nodejs module.
// - 'window' if the code is executed in a browser, or 'undefined' if running in a terminal due to the lack of 'window' global variable.
,
;
console.log(this_in_objects.propB());
// Returns "let's figure THIS out!"
console.log(this_in_objects.propC());
// Returns 'undefined'
console.log(this_in_objects.propD()());
// Returns "let's figure THIS out!"
// Notice the double round brackets to call the nested anonymous functions.
console.log(this_in_objects.propE.propE_2());
// Returns "value of propE.propE_1"
console.log(this_in_objects.propF.propF_2());
// Returns 'undefined'
this_in_objects.propX = function ()
return this.propA;
// Returns the value of this_in_objects.propA as expected.
;
this_in_objects.propA = 'The new value of propA !';
console.log(this_in_objects.propX());
// Returns "The new value of propA !",
// even though 'propA' value was changed AFTER declaring the function,
// returning the value of 'propA' at the time of function execution, not at the time of declaration.
这是基于以下信息:
Meaning of "this" in node.js modules and functions What is the 'global' object in NodeJS https://www.w3schools.com/js/js_arrow_function.asp我希望这会有所帮助,如果我错过了 this
的值可能不同的任何情况,请在 cmets 中告诉我。
【讨论】:
【参考方案7】:这里我想强调一下 global 的一个属性!
你放在那里的东西也可以直接访问
(确保检查属性标题和部分)
在带来财产之前!让我们重新定义全局!
global 是特定于 nodejs 的 语言关键字 并引用 全局命名空间对象
正如其他答案中已经描述的那样!模块中的***范围!不是全球性的!并且仅限于该模块!
因此,当您在一个模块中声明变量时,您无法在另一个模块中访问它!
https://nodejs.org/api/globals.html#globals_global
全局命名空间在给定进程的任何地方都可以访问!在所有模块中!这包括您自己的模块和第三方模块!
节点 repl 中的控制台日志记录全局将给出:
Welcome to Node.js v13.14.0.
Type ".help" for more information.
> console.log(global)
<ref *1> Object [global]
global: [Circular *1],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setInterval: [Function: setInterval],
setTimeout: [Function: setTimeout]
[Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
,
queueMicrotask: [Function: queueMicrotask],
clearImmediate: [Function: clearImmediate],
setImmediate: [Function: setImmediate]
[Symbol(nodejs.util.promisify.custom)]: [Function (anonymous)]
undefined
属性:你放在那里的东西也可以直接访问
我想带的是这个!我在探索 laravel-mix 代码源时注意到了这一点!
如果你在 global 对象上设置了一些东西!就像
global.Hola = print: () => console.log("Hola") ;
。然后,您可以在项目代码中的任何位置(多个文件 [模块] 和整个节点流程代码)直接通过其名称访问变量!意思是Hola.print()
代替global.Hola.print()
!
这里是上面示例的 node repl 屏幕截图:
> global.Hola = print: () => console.log('Hola')
print: [Function: print]
> Hola.print()
Hola
undefined
不错的财产!这就是全局命名空间!
您会注意到clearInteraval
、clearTimeout
、setInterval
、setTimeout
等方法都在那里定义!我们过去常常通过那里的名字直接访问它们!
Laravel 混合示例
这里有一些来自 laravel-mix 代码源的例子!它用在哪里!
如果您打开此文件: https://github.com/JeffreyWay/laravel-mix/blob/master/src/components/ComponentRegistrar.js
您注意到在导入部分没有! Mix
既不是变量Config
!
但是它们被使用并且是代码的一部分!我当时想:what the heck
!
死代码:
let Assert = require('../Assert');
let Dependencies = require('../Dependencies');
let mergeWebpackConfig = require('../builder/MergeWebpackConfig');
在第68行:(link here)可以看到Mix
类变量的用法!
对于第 178 行的 Config
也是如此 (link here)
当我第一次看到它时!并检查导入部分!并使用 github 参考功能(一无所有)!我是What the heck
!
后来我检查了Mix.js 文件!还有上课!我找到了设置它们的代码!我得到了直觉并在谷歌上搜索!
冲突以及为什么要使用全局命名空间
设置全局变量的问题是覆盖和冲突!这会导致错误和意外行为,直至完全崩溃!如果模块开始不加思索地使用它!一个模块将为另一个模块拧紧!就像使用第三方模块一样!想象一下模块request
将设置Config var!你也设置了它!甚至是另一个第三方模块!他们都依赖它!一个将为另一个模块拧紧它!
简单地说!我们不应该使用全局变量! 不不! 是的!
这一切都取决于!
模块最好不要这样做!这样模块就完全隔离了!而且它更健壮!一般是在某个模块中设置变量!并且每次都导入!使用依赖注入...等
然而,在许多情况下,使用全局命名空间更灵活!
您可以这样做,不用担心!如果您要构建服务器! Config 对象 可以在全局上进行! 命令行界面工具或脚本!一些直接运行的进程!
在构建模块时通常不要使用全局范围! 一个包裹! 图书馆! 一个组件! 可以重复使用! (可重复使用的跨项目!没有全局范围!隔离它)!
Laravel mix 是一个用于生成 webpack 配置的包!这可以作为 cli 工具和进程运行!
然而如果 Config 变量也是由 Webpack 或一些社区插件或加载器设置的!那么问题可能会因覆盖而发生!
在命名中添加一个域可以使其更安全变得简单!例如Mix_Config
!
【讨论】:
以上是关于NodeJS 中的“全局”对象是啥的主要内容,如果未能解决你的问题,请参考以下文章