Help us understand the problem. What is going on with this article?

あまり誰も教えてくれないネタjavascript小話

More than 5 years have passed since last update.
  • スコープの話を見てたら思い出したので話の小ネタに。
  • javascriptをそこまで熟知していない人に話すと結構驚かれる話。
  • ついでにプラスアルファ。
  • こういうときにどういうタイトルをつけるのがベストなのか分からない。

  • 05/06追記:undefinedの項に訂正があります

グローバルスコープってwindowのことだよ

  • 多分ブラウザ上で動くjavascriptに限った話だとは思いますが。
  • nodeとかだとどうなるんでしょうか。
  • グローバルスコープやグローバル変数という言葉の正しさは、分かりやすさを優先するためスルーしてます。

だからvarがあっても関数の中からグローバル変数を使えるよ

var a = 1;
function hoge(){
  var a = 2;
  alert(a); // 2
  alert(window.a); // 1
}
hoge();

そのalertもwindowのものだから

  • いわゆるグローバル関数と呼ばれているものはwindow.をつけても呼び出せます。
window.alert(1);// 1

ということはつまり、

window.は省略できるよ

  • さっきの逆バージョン
//window.open(url);
open(url);

//window.setTimeout(fn,100);
setTimeout(fn,100);

  • alertwindow.alertwindow.openopenと説明しているサイトや書籍には遭遇したことが無いんですが、付ける付けないの基準は何なんでしょうね。

グローバルスコープって言うか、windowオブジェクトスコープなのです

  • ほら、javascriptって一応オブジェクト指向ですから。
this.a = 100;
alert(a); // 100
alert(window.a); //100

var c = 100;
var a = {
  b: function(){ alert(this.c) },
  c: 200
}
a.b(); // 200
d = a.b;
d(); // 100

  • 説明
d = a.b; //ここがつまり、window.d = a.b;
d(); // そして、window.d() なので、alert(window.c);となり、 var c = 100 が window.c = 100を意味する。

alertはalertできるよ

  • だいたい 「何言ってんだコイツ」 と言う顔で見られます。

やったこと無い人はやってみよう

alert(alert); // どうなるかはみんなでやってみよう
  • そもそもjavascriptにおいては、関数も変数なのでこういうことができるわけです。
  • 変数と言うことは、つまり・・・

alertは代入できるよ

hoge = alert;
hoge("ほげー");

alertの書き換えも出来るよ

alert = 100;
console.log(alert); // 100
  • 元々のalertが使えなくなるからやっちゃ駄目だよ。
alert = confirm;
alert("もう何がなんだか");
  • こんなことも出来るよ。メリットは無いけど。

undefinedは変数 (追記)変数だった頃がありました

  • これは結構有名だと思うんですが。
  • 追記:undefinedが変数だったのは昔の話で、今は定数なので書き換えできません。下記の内容は全部消しても問題ない内容に成り下がったのですが、自分への戒めのために残してあります。

書き換え可能

var a;
console.log(a == undefined); // true
undefined = 100;
console.log(a == undefined); // false
  • いつから定数だと錯覚していた?
  • 今日まで定数じゃないと錯覚していました。

信頼できるundefinedを作る

  • 普通undefinedをvarで定義する人はいません。
  • ということは、グローバル変数と同じなのだから、どこかで書き換えれば全てのソースで影響が出ることも考えられます。
  • なので、信頼できるundefinedを作り自分のライブラリ内だけでも保護するわけです。
undefined = "hoge";
(function(undefined){
  var a;
  console.log(undefined == "hoge"); // false
  console.log(a == undefined);  // true
})();
  • 渡されていない関数の引数はundefinedになることを利用しています。
  • jqueryでも使われています。
  • って書こうとしたら、1.11以降書き方が変わっていた・・・。1.11未満を見てね。

undefinedを意味する値もundefined

  • ややこしい。
var a;
console.log(typeof a); // "undefined"
  • 1.11以降のjqueryではこの方式によるunedefinedチェックに変わったようです。

まとめ

  • グローバルスコープの正体、関数も変数である証拠、undefinedをいちいち再定義する理由。その全てを説明しているサイトにはなかなか遭遇したことが無いので書いてみました。jqueryは使えるけど素のjavascriptはいまいち分からないんだよなーという方々を対象に説明したものを少し焼きなおしたものになりますが、何か一つでも「知らなかった」ことがあると幸いです。個人的にはalertをalert出来たことで、javascriptにおける関数の扱いへの理解が深まりました。どれも直接的には役に立たない話かもしれませんが、javascriptの仕様の理解への手助けにはなるのではないでしょうか。なればいいなぁ。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした