
知りたいことリスト
- GC時の扱いが異なるのか?また異なるのはなぜか?
undefined = true //=> true
となるのは何がいけないのか?- CoffeeScript などをトランスパイルした時,
undefined
やnull
がvoid 0
に置換されるのはなぜか? hoge = void 0
とhoge = null
とhoge = undefined
の違いは何か?- 結局,コーディング時は何に統一するのが良いのか?
質問者の理解度
null !== undefined //=> true
null == undefined //=> true
void 0 === undefined //=> true
undefined = true // => true
わかってないこと
JSのGCの仕組み
ベストアンサーについて
皆様大変丁寧な回答有り難うございます.
javascript の 歴史や,こういった仕様になった背景を知ろうとするきっかけになり大変勉強になりました.
回答者全員にベストアンサーを送りたいと考えているのですが,残念ですが1名にしか送ることができません.
僕なりに,ベストなアンサーは何か?ということを考えた結果.
僕の疑問点に対して,網羅的に回答しかつ,余談や OSS での例などに触れられてわかりやすいだけでなく興味深い回答をしてくださった raccy さんに ベストアンサーを送りたいと思います.
皆様,大変わかり易い回答有り難うございました.
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答5件
0
undefined グローバルオブジェクトのプロパティで、つまりは値が未定義っと言う感じです。
nullはリテラルです。
NULL値または"空"値を返す感じです。
google先生曰く「リテラルとは、プログラムのソースコードにおいて使用される、数値や文字列を直接に記述した定数のことである。」
null === undefined // false null == undefined // true
これも面白いですよね。型チェックするとfalseになったり。
voidは演算子です。
スクリプト全体を囲み、即座に実行が行われる関数式の際に、 voidはfunctionキーワードを宣言の代わりに、 式として扱うように強制することに使用出来ます。
トランスパイルしてvoid(0)が入るのは、こういう理由からではないですかね?
トランスパイルをあんまりしないので、ちゃんと読んでないんですけど(笑)
html
1<a href="javascript:void(0);">クリックしても何も起こらない</a> 2<a href="javascript:void(document.body.style.backgroundColor='green');"> 3 ここをクリックすると背景が緑になります。 4</a>
こういうのたまに見かけますよね。
ここらは重要な点ですが、わかりにくい部分であるのも確かです。
投稿2016/06/10 05:55
編集2016/06/10 07:05総合スコア368
0
nullは空というオブジェクト
undefinedは未定義状態なのでオブジェクトですらない
void 0はundefinedを返す演算子(?)
じゃ、undefinedとvoid 0は等価かというと、
undefinedはnullのような予約語ではないので代入ができる
undefined="hogehoge"
代入されたundefined変数は、ブラウザによって代入値を返す場合もあるし
undefinedを返す場合もあるようなあいまいな状況
したがって制度を高めるためにundefinedをチェックするときにはvoid 0を利用する。
以下順に
null !== undefined //=> true
※オブジェクトと未定義を厳密に比較しているのでfalse
null == undefined //=> true
※空と未定義をあいまいに比較しているのでtrue
void 0 === undefined //=> true
undefinedとundefinedを厳密に比較しているのでtrue
undefined = true // => true
単なる代入式なので成功すればtrue
チェックにはtypeofを利用するとよい
document.write(typeof null);
document.write(typeof undefined);
document.write(typeof void 0);
document.write(typeof hogehoge);//事前に宣言されてなければundefinedが返る
投稿2016/06/10 04:51
総合スコア117654
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
null
null
はキーワードなので再代入を許しません。
javascript
1null = true; // ReferenceError: Invalid left-hand side in assignment
null
はオブジェクトが存在しないことを表します。
例えば、String#match
ではマッチしなかった場合に、getElementById
では対象のIDを持つ要素が存在しなかった時に、document.onclick
では onclick
イベントハンドラが存在しない時に null
を返します。
javascript
1console.log('hoge'.match(/foo/)); // null 2console.log(document.getElementById('hoge')); // null 3console.log(document.onclick); // null
undefined
undefined
はグローバル変数です。
ES5 からグローバル変数 undefined
は書き換え不可能となりましたが、キーワードではないのでローカル変数 undefined
を定義することが出来てしまいます。
'use strict'; (function () { var undefined = true; console.log(undefined); // true console.log(Function('return this')().undefined); // undefined }()); console.log(undefined); // undefined undefined = true; // TypeError: Cannot assign to read only property 'undefined' of object '#<Window>'
一応、グローバルオブジェクトを辿れば、グローバル変数 undefined
を参照できますが、記述が長く、扱いやすいとは言えません。
javascript
1(function () { 2 var undefined = true; 3 4 console.log(Function('return this')().undefined); // undefined 5}());
undefined
はシステムが未定義と判断した時に返す値です。
例えば、未定義のプロパティを参照した場合に undefined
を返します。
javascript
1console.log({}[0]); // undefined
その為、一般的にオブジェクトのプロパティに undefined
を代入するコードは書きません。
未定義のプロパティと区別がつかないからです。
(厳密には in
演算子や Object#hasOwnProperty
で判断することが可能ですが、そうするだけのメリットがありません。)
void 演算子
void
演算子は常に undefined
を返す為、グローバル変数 undefined
よりは扱いやすいといえます。
javascript
1(function () { 2 var undefined = true; 3 var a; 4 5 console.log(a === void 0); // true 6 console.log(typeof a === 'undefined'); // true 7}());
typeof 演算子
typeof
演算子は存在しない変数を例外を発生させる事なく判定することが可能です。
javascript
1console.log(typeof hoge === 'undefined'); // true 2console.log(hoge === void 0); // ReferenceError: hoge is not defined
Re: MaxMellon さん
投稿2016/06/10 14:32
総合スコア18194
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。


0
ベストアンサー
GC時の扱いが異なるのか?また異なるのはなぜか?
GCは関係無いです。今回は。
undefined = true //=> true となるのは何がいけないのか?
null = true
がエラーになると言う事実と整合性がとれていないように見えるからです。JavaScriptにおいてnull値とundefined値は特別な値のように見えて、その扱いには差があります。null値を表現できるようにnull
リテラルが与えられましたが、undefined値にはグローバルオブジェクトのundefinde
プロパティしか直接の表現方法が与えられませんでした。そのため、undefined
プロパティは所詮プロパティに過ぎず、再代入が可能であり、常にundefined値であるという保証が無くなってしまいました。
しかし、ほとんどのプログラムにおいては、undefined
プロパティは、null
リテラルと同じように、常に同じundefined値であることが期待することが多く、再代入は無用なバグをうむ温床となり得ます。そこで、"use strict"
による厳密モードではエラーになるようにし、この動作自体を非推奨としました。しかし、過去の互換という観点から、非厳密モードでは未だに可能であり、無用な混乱とバグを引き起こす原因の一つになり得ます。
※ 再代入によって実際に値が変わるかどうかは処理系によるようです。古い処理系では変わるようですが、node.js(v6.2.0)では変わりませんでした。
CoffeeScript などをトランスパイルした時,undefined や null が void 0 に置換されるのはなぜか?
undefined
プロパティがundefined値であるという保証が無いからです。undefined
プロパティはグローバルオブジェクトのプロパティですので、現在のコードに再代入するようなコードが無くても、その他に読み込んだJavaScirptのコードに再代入するようなコードがあれば書き換わっている可能性があります。これを防ぐ方法はありません。
CoffeeScriptではundefined
はnull
と同様の動きにする(つまり、再代入できないし、常にundefined値になる)としています。CocoやLiveScriptではvoid
を常にundefined値になるリテラルとして定義しています。これらについて、値が保証されないundefined
プロパティは使えないため、必ずundefined値になるvoid 0
やvoid 8
を使用します。なお、8は中国のラッキーナンバーだからです。
hoge = void 0 と hoge = null と hoge = undefined の違いは何か?
hoge = void 0
は、hoge
変数に、void 0
を評価した結果であるundefined値を代入します。
hoge = null
は、hoge
変数に、null値を代入します。
hoge = undefined
は、hoge
変数に、現在のundefined
プロパティの__値__(必ずしもundefined値とは限らない)を代入します。
結局,コーディング時は何に統一するのが良いのか?
undefined
プロパティに再代入するようなコードは極めて行儀悪いコードであり、滅多に無いと推測されます。また、品質的にも、そのようなコードが含まれるライブラリ等を使うべきではありません。
自分の書いたコードについては、"use strict"
による厳密モードを強制することで、そのようなコードを書いてしまうことを防ぐことができます。"use strict"
は絶対に書くべきですし、他にも多くの恩恵を受けることができます。
このようにしてundefined
をそのまま用いてもほとんどの場合は問題が出ることは少ないでしょう。ただ、問題が出たときは、一目では理解不能なバグに見えてしまうため、苦労をする可能性があります。
私のお勧めは**「生のJavaScriptを使わない」**です。CoffeeScriptやLiveScriptを使えば、このような理不尽な仕様に悩む必要はありません。teratailで回答するための検証等をのぞき、私は生のJavaScriptを書くことはもう無いと思っています。JavaScriptを捨てて今すぐaltJSを使うべきであり、それこそが、真のJSerへの道だと私は思っています。
投稿2016/06/10 13:00
編集2016/06/10 13:02総合スコア21741
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2016/06/10 16:27 編集
2016/06/10 21:56

0
JavaScriptのvoid
は1引数の演算子で、void 0
だろうがvoid 100
だろうがvoid 'hello world'
だろうが、常にundefined
値を返します。
undefined
の代わりにvoid 0
と書くメリットは以下のものがあります。
- 文字数が3文字少ない
undefined
という名前の変数を自分で定義できるので、そのままundefined
と書いていると値が変わってしまう危険がある
そして、null == void 0
かつnull !== void 0
です。
undefined
であることをチェックする場面は多いかもしれませんが、自分から代入したい時にはnull
を使うのが一般的です。
投稿2016/06/10 04:43
総合スコア146544
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2016/06/10 04:49

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2016/06/10 06:33
2016/06/10 07:02
退会済みユーザー
2016/06/10 16:08