JSのトップレベルスコープは常にグローバルオブジェクトだと思っていた
タイトル通りですが、これに関しては疑っていなかったので個人的に割と衝撃でした。何か(?)に裏切られた気持ちです。。
もう少し詳しく書くと、JSを実行した時のグローバルスコープ(=グローバルオブジェクト)は、ブラウザ上ではwindow
で、Node.js上ではglobal
である。が、トップレベルスコープがそれぞれwindow
とglobal
ではなかった。
この記事では、トップレベルスコープについて検証していきます。
※トップレベルスコープ・・・関数とかの外側、rubyだとmain。
window
とglobal
について検証
グローバル変数について確認
まず、ブラウザ上で実行した下記のコードを見ると、window
グローバルオブジェクト内のプロパティ(グローバル変数)になっていることがわかる。
// ブラウザ上で実行varfoo='global';bar='global';(function(){foobar='global';})()console.log(window.foo);// globalconsole.log(window.bar);// globalconsole.log(window.foobar);// global
次に、同様のコードをNode.js上で確認する。
// Node.js上で実行varfoo='global';bar='global';(function(){foobar='global';})()console.log(global.foo);// undefinedconsole.log(global.bar);// globalconsole.log(global.foobar);// global
Node.jsだとglobal.foo
がundefined
になっている。var
で変数を宣言するとそのスコープの変数になり、使用しないとグローバル変数になるのは基本だが念のため確認。
(function(){foo='global';varbar='global';})();console.log(foo);// globalconsole.log(bar);// ReferenceError: foobar is not defined
var
での宣言はローカルスコープになる。→ Node.jsのトップレベルドメインでvar
付き宣言した時はエラーになる。ということは、global
はもしかしたら単純なグローバルオブジェクトじゃなくて、何か間に挟まってる??
this
を確認する
this
は呼び出しもとで値が変わるが、トップレベルスコープで実行した場合自身の値が入る。
// ブラウザ上で実行console.log(this);// window
// Node.js上で実行console.log(this);//Objet{}
ブラウザ上でthis
を確認した場合、window
=グローバルオブジェクト=トップレベルスコープになっている。
一方、nodejs上で実行した場合Object{}
になっている。
ということは、global
=グローバルオブジェクト≠トップレベルスコープ!!
結局、Node.jsのトップレベルスコープって何なんだ?
Node.jsドキュメントに以下の記載があった。
global#
Added in: v0.1.27
The global namespace object.
In browsers, the top-level scope is the global scope. This means that within the browser var something will define a new global variable. In Node.js this is different. The top-level scope is not the global scope; var something inside a Node.js module will be local to that module.
ブラウザではトップレベルスコープがグローバルスコープだが、Node.js上ではトップレベルスコープではない。var
で宣言したものはmodule
のローカル変数になると書かれている。
なので、Node.jsのトップレベルドメインでグローバル変数を定義する場合は注意が必要だ!!
と思ったが、そもそもグローバル変数使うのってあまりよくないですよね。JavaScriptについて一つ詳しくなったということで許してください。