jQuery Core Style Guidelines は、変数が定義されているかどうかを確認する2つの異なる方法を提案しています。
typeof variable === "undefined"
variable === undefined
object.prop === undefined
JQueryがグローバル変数に対して1つのアプローチを使用し、ローカルおよびプロパティに対して別のアプローチを使用するのはなぜですか?
宣言されていない変数の場合、typeof foo
は文字列リテラル"undefined"
を返しますが、IDチェックfoo === undefined
はエラーをトリガーします"foo is not defined"。
ローカル変数(knowがどこかで宣言されている)の場合、このようなエラーは発生しないため、IDチェックが行われます。
どこでもtypeof foo === "undefined"
を使用することに固執します。それは決してうまくいかない。
JQueryが2つの異なるメソッドを推奨する理由は、jQueryコードが存在する関数内で独自のundefined
変数を定義しているため、その関数内でundefined
が外部から改ざんされないためです。また、誰かが2つの異なるアプローチのベンチマークを行い、foo === undefined
の方が高速であるため、その方法を決定したことも想像できます。 [更新:コメントに記載されているように、undefined
との比較もわずかに短く、これは考慮事項となる可能性があります。]ただし、実際の状況でのゲインまったく重要ではありません。このチェックは決してボトルネックにはなりません。また、失うものは重要です。比較のためにHostオブジェクトのプロパティを評価すると、typeof
チェックは決してエラーになりません。
たとえば、XMLを解析するためにIEで次が使用されます。
var x = new ActiveXObject("Microsoft.XMLDOM");
loadXML
メソッドがあるかどうかを安全に確認するには:
typeof x.loadXML === "undefined"; // Returns false
一方:
x.loadXML === undefined; // Throws an error
UPDATE
言及し忘れたtypeof
チェックのもう1つの利点は、foo === undefined
チェックでは機能しない未宣言の変数でも機能し、実際にはReferenceError
がスローされることです。思い出させてくれた@LinusKleenに感謝します。例えば:
typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError
結論:常にtypeof
チェックを使用します。
Typeof-variantを使用するもう1つの理由:undefined
を再定義できます。
undefined = "foo";
var variable = "foo";
if (variable === undefined)
console.log("eh, what?!");
typeof variable
の結果はできません。
更新:ES5ではそうではないことに注意してください。
variable === undefined
のパフォーマンスの向上に関心のある方は、こちらをご覧ください。ただし、これはchrome最適化のみのようです。
undefined
は常に宣言されているわけではありませんが、jQueryはそのメイン関数でundefined
を宣言しているためです。したがって、内部では安全なundefined
値を使用しますが、外部では安全にするためにtypeof
スタイルを使用します。
グローバルスコープで、変数が宣言されていないか、値undefined
を持っている場合、実際にtrueを返します。
var globalVar1;
// This variable is declared, but not defined and thus has the value undefined
console.log(globalVar1 === undefined);
// This variable is not declared and thus will throw a referenceError
console.log(globalVar2 === undefined);
グローバルスコープでは、変数が宣言されているかどうかが100%わからないため、referenceErrorが発生する可能性があります。未知の変数に対してtypeof
演算子を使用すると、変数が宣言されていない場合、この問題は発生しません。
var globalVar1;
console.log(typeof globalVar1 === 'undefined');
console.log(typeof globalVar2 === 'undefined');
これは、変数が宣言されていないか、現在値typeof
を保持しているときにundefined
演算子が文字列undefined
を返すためです。
undefined
も取得されるため、この問題は発生しません。var obj = {};
console.log(obj.myProp === undefined);
ローカル変数の場合、localVar === undefined
を使用したチェックは、ローカルスコープ内のどこかで定義されている必要があります。そうでない場合、ローカルとは見なされません。
ローカルではなく、どこにも定義されていない変数の場合、チェックsomeVar === undefined
は例外をスローします:Uncaught ReferenceError:j is not defined
上記の内容を明確にするコードを以下に示します。 より明確にするためにインラインコメントに注意してください。
function f (x) {
if (x === undefined) console.log('x is undefined [x === undefined].');
else console.log('x is not undefined [x === undefined.]');
if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
else console.log('x is not undefined [typeof(x) === \'undefined\'].');
// This will throw exception because what the hell is j? It is nowhere to be found.
try
{
if (j === undefined) console.log('j is undefined [j === undefined].');
else console.log('j is not undefined [j === undefined].');
}
catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}
// However this will not throw exception
if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};
上記のコードを次のように呼び出すと:
f();
出力は次のようになります。
x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
これらのような上記のコードを呼び出した場合(実際には任意の値で):
f(null);
f(1);
出力は次のようになります。
x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
このようなチェックを行うときは、typeof x === 'undefined'
、本質的にこれを尋ねています:ソースコードのどこかに変数x
が存在する(定義されている)かどうかを確認してください (多かれ少なかれ)。 C#またはJavaを知っている場合、このタイプのチェックは実行されません。存在しない場合はコンパイルされないためです。
typeof a === 'undefined'
は、ノードv6.9.1でa === 'undefined'
より約2倍高速です。