undefined の上書き問題に対する打開案

ECMAScript 5 ではグローバル変数 undefined を書き換えることは出来ませんが、ローカル変数 undefined を宣言することは許されています。 「ではどうやって解決するのでしょうか?」というお話。
2
koichik @koichik

@Constellation @bad_at_math このパッチ http://ow.ly/6KmHr なぜ必要かわかる? 元の issue http://ow.ly/6KmHL はまぁ分かるんだけど,return のはよくわからない.

2011-10-01 20:37:52
小倉唯 @Constellation

@koichik @bad_at_math 確かJSLintはreturnするpathの存在する関数にreturnしないpathがあった場合警告したはずで, おそらくそれに合わせているのだと思います. 言語仕様的には別に問題ないです. undefinedかnullかの違いです.

2011-10-01 20:54:27
koichik @koichik

@constellation @bad_at_math とすると,本来の issue である "--harmony_typeof --harmony_weakmaps --harmony_block_scoping" で動かないってのとは別件? 実際動くし…

2011-10-01 20:58:52
小倉唯 @Constellation

@koichik @bad_at_math 一応proposalはあります http://t.co/YMdDrpcR typeof nullが"null"になるものです.ただundefinedなものをnullにするのには関係無いので, 多分JSLintの方が理由と考えられますー.

2011-10-01 21:06:42
koichik @koichik

@constellation @bad_at_math しかし,Node を make jslint しても return の警告は出ないのであった.設定の問題かな.いずれにせよ,主題と違う修正はやめて欲しいな…

2011-10-01 21:11:08
小倉唯 @Constellation

@koichik @bad_at_math あー, JSLintではなくてSpiderMonkeyのsyntax checkerだったかもしれないです(-s option). warningが出ると思います(trailing commaとかもでる)

2011-10-01 21:12:26
koichik @koichik

@constellation @bad_at_math ふむむ.さらに元ネタをよく見ると,harmony なオプションで動かないってのは主題じゃないことに気がついた.じゃあありなのかなぁ.微妙だなぁ.

2011-10-01 21:16:36
koichik @koichik

Constellation @bad_at_math ちなみに,undefined を参照するのも警告? (function(undefined) {...})(); とかなしで.

2011-10-01 21:18:39
小倉唯 @Constellation

@koichik @bad_at_math でないと思いますー(少なくともJSLint/JSHint/SpiderMonkey syntax checkでは). ただvoid 0がbest practiceだという思想もあるにはあります. (長くなったので続き…)

2011-10-01 21:27:34
小倉唯 @Constellation

@koichik @bad_at_math undefinedが変数なのでES3の時は変更, ES5になってもlocal変数として定義できるので, 本当にundefinedかどうか分からないという理由です. 個人的にはそこまで言う必要ないと思いますが...

2011-10-01 21:29:09
小倉唯 @Constellation

void 0はoperator + literalだから変数lookupより事前に畳み込めて高速という考え方もできるには出来ますが, そこまでならGlobal変数のlookupを検出かつundefinedなどCW: FFなものなら変更不可なので, 計算して埋め込んでもいいと思う.

2011-10-01 21:31:57
koichik @koichik

@constellation @bad_at_math 無条件に警告を出すわけではないのですね.Node では以前,udefined を使うべきではないという issue があって却下されてたんだけど,今回一連のパッチに void 0 への修正が含まれてるんだなぁ.うーん...

2011-10-01 21:34:50
小倉唯 @Constellation

@koichik @bad_at_math そこの選択はもう完全に趣味ですw

2011-10-01 21:44:44
小倉唯 @Constellation

自分はどちらでもいいと思ってる. undefinedが内容違うかもという指摘なら, 逆に変数としてundefinedなんて準keywordなものを定義している方を先に直すべき. (evalされたらーというならeval target scopeに他の処理を書くほうが危険)

2011-10-01 21:48:44
azu @azu_re

undefinedを上書きすべきでない と undefined = void 0; は矛盾してる。

2011-10-01 21:51:16
小倉唯 @Constellation

変数宣言はparser使えばstaticに解析可能なのでundefinedなんていう名前の変数を定義していたら全て暴き出せる. ES5になってvar s="undefined"; window[s]=true;とかも効かないので(writable:false) 今はどちらでもいい

2011-10-01 21:53:01
think49 @think49

「ES5 でもlocal変数 undefined を定義できて undefined === void 0 を保証できない」問題。そのコードが自分の管理下にあるのか管理外にあるのか、で見方が違ってくると思う。

2011-10-01 21:54:36
think49 @think49

@think49 そのコードが自分の管理下にあるのなら local変数 undefined がないことは保証できるから問題はない。管理下にないなら自分でlocal変数 undefined を定義することで解決できるはず。実際、jQuery もそうやって解決してたと思う…。

2011-10-01 21:55:59
think49 @think49

@think49 「local変数 undefined が気持ち悪い」という感覚はわかるので私なら var _undefined = void 0; にするかも。"undefined" という名前が信頼できないならユニークなローカル変数を定義した方がすっきりすると思う。

2011-10-01 21:59:43
think49 @think49

@think49 ES5 で気に入らないのは「定数」に相当する機能がないことかな。「undefined がスコープチェーンによる上書きを許す」なら上書きを許さないようにコードを書き直すべきであって、そのための機能が ES5 にはない。

2011-10-01 22:04:26
小倉唯 @Constellation

@think49 自分はundefinedは保証するのに, ObjectやArrayとかのbuiltin関数はそのまま使うというのは釣り合いがとれていないような気がします.

2011-10-01 22:07:00
think49 @think49

@Constellation あ、なるほど。いわれてみれば undefined に限定されない問題ですね。仕様を改善するとすれば Keywords を増やす方向になるのでしょうか…。

2011-10-01 22:14:20
think49 @think49

#ECMAScript には「ゆるい仕様」と「きつい仕様」がある。でも、「ゆるい仕様」が必ずしも欠点ではなくて「柔軟さ」の裏返しでもあるので大胆な仕様変更は出来ない状況なのかなーと推測してみる。

2011-10-01 22:22:00
think49 @think49

@think49 「スコープチェーンで何でも上書きできる性質」を欠点とみるか利点とみるか。「Object.prototype を拡張すべきでない論」と似た側面がある気がする。

2011-10-01 22:25:38
小倉唯 @Constellation

@think49 今の時点でも他の人のjsの中にtemplateで自分のを展開するというようなことをしない限りlocal変数はglobal以下自分のcontrol下に置けるので大丈夫だと思いますー. evalはstrict modeでlocal scopeから締め出せるので!

2011-10-01 22:26:45