什么是NodeJS中的“全局”对象

我刚刚在NodeJS环境中看到了this关键字的奇怪行为。 我用代码列出他们。 我已经用NodeJS v6.x和一个JavaScript文件运行这个代码。

在使用一行代码进行testing时,无论是否使用'use strict'语句,都会指向一个空对象{}

 console.log(this) 

但是,当我在一个自我执行的函数内运行这个语句时,

 (function(){ console.log(this); }()); 

这是打印一个真正的大对象。 在我看来, NodeJS环境创build的全局执行上下文对象。

'use strict'语句执行上述function的同时,预计打印undefined

 (function(){ 'use strict'; console.log(this); }()); 

但是,在使用浏览器(我只使用Chrome进行testing)的同时,前三个例子产生window对象,最后一个undefined按预期undefined

浏览器的行为是可以理解的。 但是,在NodeJS情况下,它不会创build执行上下文,直到我包装在一个函数内?

那么, NodeJS大部分代码都运行一个空的全局 object

而在浏览器中,全局作用域是window对象,在nodeJS中,模块的全局作用域是模块本身,所以当你在nodeJS模块的全局作用域中定义一个variables时,它将在本地模块中。

您可以在NodeJS文档中阅读更多关于它的信息

全球

<Object> The global namespace object.

在浏览器中,顶级范围是全局范围。 这意味着在浏览器中,如果你在全局范围内,var将会定义一个全局variables。 在Node.js中,这是不同的。 顶级范围不是全球范围; 在一个Node.js模块中的var的东西将是本地模块。

当你写代码时,在你的代码中:

  • console.log(this)在一个空的js文件(模块)中,它将打印一个空对象{}指向你的空模块。
  • console.log(this); 在一个自调用函数中, this将指向包含所有NodeJS公共属性和方法(如require()moduleexportsconsolerequire()的全局nodeJS作用域对象。
  • console.log(this)在自我调用函数内部使用严格模式 ,它将打印为undefined的自调用函数在严格模式下没有默认的本地作用域对象。

很有意思:

 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) 不确定的,因为它不严格模式的对象自动装箱。 这意味着在这种情况下没有根对象。 如果你不使用严格模式,那么你的代码被父范围装箱。正如你在输出中看到的那样,在nodejs中有很多关于节点内部信息的信息。

1) ,输出是一个空对象,因为在节点模块的顶层代码中,这相当于module.exports,module.exports在本例中是空的。

首先在节点环境中的全局上下文的文档

在浏览器中,顶级范围是全局范围。 这意味着在浏览器中,如果你在全局范围内,var将会定义一个全局variables。 在Node.js中,这是不同的。 顶级范围不是全球范围; 在一个Node.js模块中的var的东西将是本地模块。

每个JS文件被视为一个模块。 节点自动将JS文件的代码封装在一个自带的IIFE中,其中包括exports, require, module, __filename, __dirname作为函数的参数。

下面是使用node-debug的执行上下文的屏幕截图

节点调试

如果你运行下面的代码,打印true ,这意味着this是指node.js中的exports 。 最好在这个答案解释。

 console.log(this === exports); 

这意味着在执行时,代码被包装在类似下面的Node.js中,使用包装函数上下文将代码从全局上下文中分离出来。

  var context = (function (exports, require, module, __filename, __dirname) { console.log(this) //This is my code }); var module = {exports:{}}; context.apply(module.exports, [module.exports, require, module, "FILE_NAME", "DIR_NAME"]); 

回答下一个问题完全参考这个文件 :

与其他语言相比,函数的this关键字在JavaScript中的performance有点不同。 它在严格模式和非严格模式之间也有一些区别。

所以当你执行这个代码

 (function(){ console.log(this); }()); 

打印global对象并use strict模式打印undefined


记得:

在浏览器中,函数不像IIF / wrapper函数上下文那样被封装在节点中,而是直接在window对象上执行。 因此,调用上下文因Node.js和Browser而异。

也读这个 。