web-dev-qa-db-ja.com

JavaScriptで、未定義が上書きされていないと想定するのは本当に危険なのでしょうか。

誰かがundefinedに対するテストについて言及するたびに、 指摘されているundefinedはキーワードではないため、- "hello" なので、 使用する必要がありますtypeof x == "undefined"代わりに。これは私にはばかげているようです。誰もそれをすることはないだろうし、彼らがそれをしたなら、彼らが書いたコードを決して使用しないのに十分な理由だろう...

私は 1つの例 を誤ってundefinednullに設定した人を見つけました。これは、undefinedが上書き。しかし、彼らがそれを行った場合、バグは検出されなくなり、私はそれがいかに優れているかを確認できません。

C++では、誰もが#define true falseですが、trueを避けて0 == 0代わりに。あなたは、誰もそれをするのに十分なほど大きなジャークにはならないだろうと思い込んでいます。

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

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

85
Cosmologicon

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

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

あなたがすべきことnotすることはあなた自身のスコープされた可変のundefinedを作成することです:

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

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

(function () {
    const undefined = void 0;
})();
56
Ry-

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


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

ブラウザが何歳であっても、本当にndefinedundefinedを取得するための非常に良い方法があります。

_(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が値に設定されたことがない場合(setundefinedであるのとは逆に) 、xif(x === undefined)などの別の方法で読み取ると、エラーがスローされます。ただし、これはオブジェクトのプロパティには適用されないため、yが常にオブジェクトであることがわかっている場合、if(y.x === undefined)は完全に安全です。

40
ThiefMaster

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

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

とはいえ、何かをundefinedと比較するときに誰かが=ではなく==を書き込むと、未定義の変数がエラーで設定される可能性があります。

19
Lucero

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

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

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

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

(function( window, undefined ) {

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

編集:PSあなたが本当に私の意見を望んでいるなら、私はそれがまったく危険ではないとあなたに言います。欠陥を引き起こす可能性が非常に高いもの(undefinedへの割り当てなど、これは明らかに文書化されたリスクのある動作です)は、それ自体が欠陥です。リスクであるのは欠陥です。しかし、それは私の見解であり、私はその見方を保つ余裕があります。私はあなたにお勧めしたいので、私は私のユースケースの質問に答えました。

3
shannon

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

Maybe公用のライブラリを作成している場合、いくつかの手法を使用して、ユーザーがライブラリを変更しないようにすることができます。しかし、この場合でも、ライブラリではなく、問題です。

3
Bart Calixto

ECMAScript 5.1をサポートするブラウザーをそのままコーディングする場合、コードでundefinedを使用できます 言語仕様に従って不変

this 互換表または thiscaniuse ECMAScript 5も参照してくださいすべての最新ブラウザ(IE 9+)は不変のundefinedを実装しています。

2

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

1
kirk.burleson

まず第一に、あなたのコードが壊れたとしても、おそらく他の開発者があなたがそれを「ジャークにしようとしている」からではないでしょう。

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を使わないのですか?

0
Octopus