2017-04-26 12 views
9

NodeJS環境でthisキーワードの奇妙な動作が見られました。私はコードでそれらをリストしています。私はNodeJS v6.xでこのコードを実行しました。ファイルはJavaScriptです。NodeJSの 'グローバル'オブジェクトとは

'use strict'ステートメントの有無にかかわらず、1行のコードでテストしている間に、空のオブジェクト{}を指しています。

console.log(this) 

しかし、私はのような機能を実行する自己内のステートメントを実行している、

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

それは本当に大きなオブジェクトを印刷しています。私には、NodeJS環境で作成されたグローバル実行コンテキストオブジェクトと思われます。

そして、'use strict'文で上記の機能を実行する予想通り、それはundefined

(function(){ 
    'use strict'; 

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

を印刷しています。しかし、(私だけChromeでテストしてみた)ブラウザでの作業中に、最初の3例は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.

は、トップレベルのスコープはグローバルスコープです。つまり、グローバルスコープにある場合は、ブラウザーで が、何かがグローバル変数 を定義することを意味します。 Node.jsではこれが異なります。トップレベルのスコープはグローバルスコープではなく です。 var Node.jsモジュール内の何かは、そのモジュールにローカルな になります。

そして、あなたのコード内であなたが書いた:空のjsファイル(モジュール)で

  • console.log(this)それはあなたの空のモジュールを参照する空のオブジェクト{}を印刷します。自己呼び出し関数内
  • console.log(this);
  • thisは全てNodeJS共通プロパティおよびメソッドを含むグローバルnodeJSスコープオブジェクトをポイントするよう自己呼び出し関数内 strict moderequire()moduleexportsconsole ...
  • console.log(this)として自己起動関数はにデフォルトのローカルスコープオブジェクトを持たないため、undefinedが出力されます。
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)); 
}()); 

が生成されます:3)

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 

このそれが厳密モードでオブジェクトにautoboxedれないよう不定あります。つまり、このコンテキストにはルートオブジェクトがありません。あなたが厳密なモードを使用しない場合、あなたのコードは親スコープによって囲まれています。出力で見ることができるように、nodejs内にはノード内部のものに関する多くの情報があります。

1)の出力は空のオブジェクトです。これは、ノードモジュールのトップレベルコードでは、これはmodule.exportsと等価であり、module.exportsはこの例では空であるためです。

1

ノード環境でグローバルコンテキストにdocumentationとブラウザで

を開始するには、トップレベルのスコープはグローバルスコープです。つまり、ブラウザでグローバルスコープにいる場合は、何かがグローバル変数を定義します。 Node.jsではこれが異なります。トップレベルのスコープはグローバルスコープではありません。 var Node.jsモジュール内の何かは、そのモジュールに対してローカルになります。

各JSファイルはモジュールとして扱われます。ノードは自動的にJSFファイルのコードをパラメータとしてexports, require, module, __filename, __dirnameを持つ自己IIFEにラップします。以下は

あなたはthisがnode.js.にexportsを参照し、以下のコード、プリントtrueを実行する場合node-debug

node-debug

を使用して実行コンテキストのスクリーンショットですこのanswerで最もよく説明されています。実行時にコードがラッパー関数コンテキストを使用して、グローバルコンテキストから、あなたのコードを分離するNode.jsの中で以下のように似たようなラップされている意味

console.log(this === exports); 

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を参照してください。

関数のthisキーワードは、他の言語に比べて、JavaScriptで少し異なる動作をします。また、厳密モードと非厳密モードの間にいくつかの違いがあります。

ので、あなたは、このコードを実行するとき

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

プリントはglobal対象とuse strictモードプリントundefined


には覚えておいてください:

は、ブラウザでの機能ではありません包まれたIIFE /ラッパー関数のコンテキストでは、ノードのように、直接windowオブジェクトで実行されます。したがって、呼び出しコンテキストはNode.jsとBrowserによって異なります。

thisも読んでください。

関連する問題