6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JavaScriptのトップレベルスコープは常にグローバルスコープではなかった

Posted at

JSのトップレベルスコープは常にグローバルオブジェクトだと思っていた

タイトル通りですが、これに関しては疑っていなかったので個人的に割と衝撃でした。何か(?)に裏切られた気持ちです。。
もう少し詳しく書くと、JSを実行した時の**グローバルスコープ(=グローバルオブジェクト)**は、ブラウザ上ではwindowで、Node.js上ではglobalである。が、トップレベルスコープがそれぞれwindowglobalではなかった。
この記事では、トップレベルスコープについて検証していきます。

※トップレベルスコープ・・・関数とかの外側、rubyだとmain。

windowglobalについて検証

グローバル変数について確認

まず、ブラウザ上で実行した下記のコードを見ると、windowグローバルオブジェクト内のプロパティ(グローバル変数)になっていることがわかる。

// ブラウザ上で実行
var foo = 'global';
bar = 'global';
(function(){
  foobar = 'global';
})()

console.log(window.foo); // global
console.log(window.bar); // global
console.log(window.foobar); // global

次に、同様のコードをNode.js上で確認する。

// Node.js上で実行
var foo = 'global';
bar = 'global';

(function(){
  foobar = 'global';
})()

console.log(global.foo); // undefined
console.log(global.bar); // global
console.log(global.foobar); // global

Node.jsだとglobal.fooundefinedになっている。
varで変数を宣言するとそのスコープの変数になり、使用しないとグローバル変数になるのは基本だが念のため確認。

(function(){
  foo = 'global';
  var bar = 'global';
})();

console.log(foo); // global
console.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について一つ詳しくなったということで許してください。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?