2017-04-26 79 views
9

我剛在NodeJS環境中看到this關鍵字的奇怪行爲。我用代碼列出了它們。我已使用NodeJS v6.x運行此代碼,單個文件爲JavaScript什麼是NodeJS中的'global'對象

使用以下一行代碼進行測試時,無論是否使用'use strict'語句,都會指向一個空對象{}

console.log(this) 

但是,當我運行一個自執行之類的函數內聲明,

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

它打印一個非常大的對象。在我看來,由NodeJS環境創建的全局執行上下文對象。

雖然有'use strict'語句執行上述功能,果然它的打印undefined

(function(){ 
    'use strict'; 

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

但是,同時與瀏覽器的工作(我只用Chrome測試),前三個例子得到window對象如預期的那樣,最後一個給出undefined

瀏覽器的行爲是很容易理解的。但是,在NodeJS的情況下,它是否創建執行上下文,直到我包裝在一個函數內?

因此,NodeJS中的大部分代碼都以空的全局運行object

+1

看看:http://stackoverflow.com/questions/22770299/meaning-of-this-in-node-js-modules-and-functions –

回答

11

在瀏覽器中,全局範圍是window對象,在nodeJS中,模塊的全局範圍是模塊本身,所以當您在nodeJS模塊的全局範圍內定義一個變量時,它將在本地模塊中。

您可以閱讀NodeJS documentation更多地瞭解它,它說:

全球

<Object> The global namespace object.

在瀏覽器中,頂級的範圍是全球範圍。這意味着如果你在全局範圍內,那麼瀏覽器中的 var變量將定義一個 全局變量。在Node.js中,這是不同的。頂級範圍是 不是全球範圍; var Node.js模塊內的某些東西對於該模塊來說是 。

而且在你的代碼,當你寫:

  • 在一個空的JS文件console.log(this)(模塊),它會打印一個空對象{}指你的空模塊。
  • console.log(this);自調用函數中,this將指向包含了所有常見的NodeJS屬性和方法在全球範圍內的NodeJS對象,如require()moduleexportsconsole ...
  • console.log(this)strict mode自調用函數中它將打印undefined作爲自調用函數在Strict mode中沒有默認的本地作用域對象。
2

很有意思:

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)未定義因爲它不autoboxed在嚴格模式的對象。這意味着在這種情況下沒有根對象。如果你不使用嚴格模式,那麼你的代碼被父範圍裝箱。正如你在輸出中看到的,在nodejs中有很多關於節點內部信息的信息。

1)輸出是一個空對象,因爲在節點模塊的頂級代碼中,這相當於module.exports,module.exports在此示例中爲空。

1

要與documentation全球範圍內的節點環境

在瀏覽器中啓動,頂級的範圍是全球範圍。這意味着在瀏覽器中,如果你在全局範圍內,var的東西將定義一個全局變量。在Node.js中,這是不同的。頂級範圍不是全球範圍;在Node.js模塊內的var內容對於該模塊是本地的。

每個JS文件將被視爲一個模塊。節點自動換帶exports, require, module, __filename, __dirname在自IIFE一個JS文件作爲參數傳遞給函數的代碼。

下面是執行上下文的使用屏幕截圖node-debug

node-debug

如果運行下面的代碼,印刷品true這意味着thisexports在node.js中在此answer最好的解釋。

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"]); 

答到下一個點是指這個documentation完全:相對於其他語言

函數的此關鍵字的行爲在JavaScript有點不同。它在嚴格模式和非嚴格模式之間也有一些差異。

所以,當你執行這個代碼

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

打印的global對象和use strict模式打印undefined


記住:

在瀏覽器的功能是不包裹通過IIFE/wrapper功能上下文中的節點,它直接在window對象上執行。因此,調用上下文因Node.js和Browser而異。

也讀this