未定義が上書きされないと仮定することは、JavaScriptで実際にどれほど危険ですか?


86

誰でもに対してテストを言及するたびにundefinedそれは先の尖ったアウトですundefinedので、キーワードではありません、それはに設定することができ"hello"て、あなたが使用する必要があります typeof x == "undefined"代わりに。これは私にはばかげているようです。誰もそれをすることはありません、そしてもし彼らがそうするなら、彼らが書いたコードを決して使わないのに十分な理由でしょう...そうですか?

誤ってに設定した人の例1つ見つけました。これは、上書きされないと想定しないようにする理由として挙げられました。しかし、もし彼らがそれをしていたら、バグは検出されなかったでしょう、そして私はそれがどのように良いのか見当がつかないのです。undefinednullundefined

C ++では、誰もが言うことが合法であることをよく知っていますが#define true false、代わりにtrue使用しないようにアドバイスする人は誰もいません0 == 0。あなたは、誰もそれをするのに十分な大きさではないだろうと思い込んでいます。もしそうなら、彼らのコードを二度と信用しないでください。

これは、他の誰かがundefined(故意に)割り当てた場所で実際に誰かを噛み、コードを壊したことがありますか、それともこれは架空の脅威ですか?私は自分のコードをわずかに読みやすくするためにチャンスを利用したいと思っています。これは本当に悪い考えですか?

繰り返しになりますが、私は再割り当てされた未定義から保護する方法を求めていません。私はすでに100回書かれたそれらのトリックを見てきました。私はそれらのトリックを使わないことがどれほど危険かを尋ねています。


7
喜んで申し上げますが、与えられた3つの答えのどれもが質問にうまく答えられるとは思えません。リンクした回答の再ハッシュを求めていないことを明確にしようとしましたが、それでも得られたものです。たとえそれが私が求めていたものでなくても答えを受け入れないことがゴーシュであると考えられるならば、私に知らせてください、そして私は先に進んでそれを受け入れます!
Cosmologicon 2012年

1
しかし、すべての事実がここに示されていると思います。だから、あなたが言っているのは、代わりに主観的な答えや意見が欲しいということです。それは意見の不一致につながるだけです。これが、質問のタイトルで「ベストプラクティス」というフレーズが許可されていない理由です。あなたはそれがあなたのシナリオでどれほど危険であるかを知ることができる唯一の人です。また、すべての「変数」を制御しない一般的なライブラリを作成している場合は、function(undefined){}ラッパーが優れた答えのようです。それを使ってその答えを受け入れてみませんか?
シャノン2012

4
誰の誰かの再定義を心配した場合undefined、あなたは誰かの再定義についての詳細を心配する必要がありXMLHttpRequest、またはalert。使用するすべての関数windowが再定義されている可能性があります。そして、同僚が偶然にそれをしているのではないかと心配しているのなら、なぜ彼らがそうしないと信じているのwindow.addEventListener = "coolbeans"ですか?答えはそれについて心配することではありません。誰かが悪意を持ってJSをページに挿入している場合、とにかくあなたはうんざりしています。そもそもそれが起こらないように取り組んでください。
クリスミドルトン

回答:


56

いいえ、ありません。これは主に、ECMAScript5にほとんど準拠している最新のブラウザーで開発しているためです。ES5標準でundefinedは、これが読み取り専用になることが規定されています。ストリクトモードを使用している場合(そうする必要があります)、誤って変更しようとするとエラーがスローされます。

undefined = 5;
alert(undefined); // still undefined
'use strict';
undefined = 5; // throws TypeError

すべきでないのは、独自のスコープ付きの可変を作成することですundefined

(function (undefined) {
    // don't do this, because now `undefined` can be changed
    undefined = 5;
})();

定数は問題ありません。まだ不要ですが、問題ありません。

(function () {
    const undefined = void 0;
})();

最初のステートメントは、開発中に誤ってundefinedを上書きしないことを保証するだけであり、クライアントコンピューターで他のコードを実行するときにも同じ脅威をもたらします。
bennedich 2012年

1
@bennedich:私はその問題に遭遇したことがないと言っていましたが、これがあなたがすべきことです
–ry-

1
@bennedich他の変数を誤って上書きする可能性は同じではありませんか?
Ates Goral 2016年

40

適切なコードはそのようなことをしません。しかし、スマートな開発者や使用しているプラ​​グイン/ライブラリ/スクリプトが何をしたかを知ることはできません。一方、それは非常にまれであり、最近のブラウザは上書きundefinedをまったく許可しません。そのため、開発にそのようなブラウザを使用している場合、コードが上書きしようとしているかどうかすぐにわかります。


そして、あなたがそれを求めなかったとしても、多くの人々は、より一般的な「再定義から保護する方法」の問題を探すときにおそらくこの質問を見つけるundefinedでしょう、それで私はとにかくそれに答えます:

ブラウザの古さに関係なく、真に未定義 を取得するための非常に良い方法がありますundefined

(function(undefined) {
    // your code where undefined is undefined
})();

これは、指定されていない引数が常にであるために機能しますundefined。jQueryを使用している場合など、実際の引数を受け入れる関数を使用してこれを行うこともできます。通常、次のように正常な環境を確保することをお勧めします。

(function($, window, undefined) {
    // your code where undefined is undefined
})(jQuery, this);

そうすれば、その無名関数の内部で次のことが当てはまると確信できます。

  • $ === jQuery
  • window === [the global object]
  • undefined === [undefined]

ただし、typeof x === 'undefined'実際に必要な場合があることに注意してください。変数xが値に設定されたことがない場合(に設定されているのとは逆にundefined)、xなどの別の方法で読み取るとif(x === undefined)エラーがスローされます。ただし、これはオブジェクトプロパティには適用されないため、それyが常にオブジェクトであることがわかっている場合if(y.x === undefined)は、完全に安全です。


2
x値に設定されていないというあなたの声明は完全に真実ではありません(jsfiddle.net/MgADzを参照)。むしろ、実際に本当に定義されていない場合です(jsfiddle.net/MgADz/1を参照)。
–ry-

7
繰り返しますが、誰かが誤ってundefined = someVariableそれがバグだと言って、あなた物事を壊したい場合。少なくとも私はそうします。
Cosmologicon 2012年

2
未定義を上書きする縮小されたレガシースクリプトを含むコードベースで作業しました。スクリプトを書き直す時間も予算もありませんでした。これは、typeof x == "undefined"が必要な例です。それほど奇妙ではなく、おそらく良い習慣。
Damen TheSifter 2012

2
すべての例で関数の追加引数として「未定義」が使用されている理由に興味がありますか?ただし、誰かがエラーによって1つの追加パラメーター(定義済み)を渡し、すべてのロジックが失敗する場合があります。function(){var_undef;のようなものを使用してみませんか。if(someVal == _undef){何かをする}};
Oleksandr_DJ

4
@Oleksandr_DJその通り。あなたがその値メイクアップ知っているのundefinedとすることを割り当てるundefinedスコープインチ 「多すぎる」引数を渡した場合は、上書きできるように開いたままにしないでくださいundefinedこれはエラーを招き、本質的に非防御的なパターンです。特に、Luceroが指摘しているようにundefinedスコープ内で確実な値を取得するための非常に簡単な代替手段がある場合はそうです。
ラフィン2014年

19

これには簡単な解決策がありvoid 0ます。常に定義されていないものと比較してください。

==値を強制する可能性があるため、避ける必要があることに注意してください。代わりに===(および!==)を使用してください。

とは言うものの、誰かが何かをと比較する=代わりに書き込むと、未定義の変数がエラーによって設定される可能性があります。==undefined


IMO、これがベストアンサーです。
abhisekp 2015

1
この互換性の表に示さfoo === void 0foo === undefinedているように、読み取りがスムーズではなく、不変undefinedが最新のブラウザー(IE 9以降)で完全にサポートされていることを考慮してください。
Daniel AR Werner

3

使用するコードを知っているのはあなただけであり、したがってそれがどれほど危険かを知っています。この質問には、回答したいことを明確にした方法で回答することはできません。

1)チームポリシーを作成し、未定義の再定義を禁止し、より一般的な使用法のために予約します。既存のコードをスキャンして、未定義の左割り当てを探します。

2)すべてのシナリオを制御していない場合、コードがユーザーまたはポリシーが制御している状況以外で使用されている場合、明らかに答えは異なります。スクリプトを使用するコードをスキャンします。必要に応じて、未定義の左割り当ての統計をWebでスキャンしますが、代わりにここで回答#1または#3を追求する方が簡単なので、それが行われたとは思えません。

3)そして、その答えが十分でない場合、それはおそらく、あなたが別の答えを必要としているからでしょう。おそらく、企業のファイアウォール内で使用される人気のあるライブラリを作成していて、呼び出し元のコードにアクセスできない可能性があります。次に、ここで他の細かい答えの1つを使用します。人気のあるjQueryライブラリがサウンドのカプセル化を実践し、次のことを開始することに注意してください。

(function( window, undefined ) {

あなただけがあなたが求める特定の方法であなたの質問に答えることができます。これ以上何を言うことがありますか?

編集:ps本当に私の意見が必要な場合は、まったく危険ではないと言います。欠陥を引き起こす可能性が非常に高いもの(未定義への割り当てなど、明らかに十分に文書化された危険な動作)は、それ自体が欠陥です。リスクとなるのは欠陥です。しかし、それは私のシナリオにあり、その視点を保持する余裕があります。私がお勧めするように、私は自分のユースケースの質問に答えました。


3

未定義に対してテストしても安全です。あなたがすでに述べたように。それをオーバーライドするコード(非常に改善可能)に到達した場合は、それを使用しないでください。

たぶん、あなたは公共の使用のためのライブラリを作成している場合は、ユーザーの変更にそれを避けるために、いくつかのテクニックを使用することができます。しかし、この場合でも、それは彼らの問題であり、あなたの図書館ではありません。



1

まったく危険ではありません。ES3エンジンで実行している場合にのみ上書きでき、それ以上使用される可能性は低くなります。


0

まず第一に、コードが壊れた場合、それはおそらく、他の開発者があなたが言ったように「ジャークになろうとしている」からではありません。

それundefinedはキーワードではないのは事実です。しかし、それグローバルレベルのプリミティブです。これは次のように使用することを目的としていました(developer.mozilla.orgの「undefined」を参照 )。

var x;
if (x === undefined) {
    // these statements execute
}
else {
    // these statements do not execute
}

これに対する一般的な代替手段(これもMDNから)であり、私の意見では、より良い方法は次のとおりです。

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
    // these statements execute
}

if(x === undefined){ // throws a ReferenceError

}

これにはいくつかの利点がありますが、(コメントから)明らかなのは、xが宣言されていないときに例外がトリガーされないことです。また、MDNも、使用することが重要であると指摘していることは注目に値します===オーバー==:最初のケースであるため

var x=null;
if (x === undefined) {
    // this is probably what you meant to do
    // these lines will not execute in this case
}
else if (x == undefined) {
    // these statements will execute even though x *is* defined (as null)
}
else {
    // these statements do not execute
}

これは、見過ごされがちなもう1つの理由であり、すべての場合に2番目の選択肢を使用する方がおそらく良いでしょう。

結論:最初の方法でコーディングすることは間違いではなく、確かに危険ではありません。それに対する例として使用している(上書きできる)という引数は、代替をでコーディングするための最も強力な引数ではありませんtypeof。ただし、typeof特に1つの理由から、使用の方が強力です。varが宣言されていない場合でも、例外はスローされません。==代わりにを使用すること===はよくある間違いであると主張することもできます。その場合、期待どおりに機能しません。では、なぜ使用しないのtypeofですか?


1
「これにはいくつかの利点がありますが、明らかなのは、xが宣言されていないときに例外がトリガーされないことです。」これをまっすぐにしましょう。宣言されていない変数を使用するときに発生する例外を黙って無視することは利点だと思いますか?それは非常にエラーが発生しやすいようです。それがひどい不利益ではないと思う理由を説明できますか?
Cosmologicon 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.