Javascript 言語の設計は十分に厳密ではないため、注意しないと多くの場所でエラーが発生する可能性があります。
例として、次の状況を考えてみましょう。
次に、グローバル オブジェクト myObj が存在するかどうかを確認する必要があります。存在しない場合は、それを宣言します。自然言語で記述されたアルゴリズムは次のとおりです:
if (myObj notowned){
Declare myObj;
}
このコードを書くのは簡単だと思うかもしれません。しかし実際には、含まれる文法上の問題は私たちが想像するよりもはるかに複雑です。 Juriy Zaytsev 氏は、JavaScript オブジェクトが存在するかどうかを確認する方法は 50 以上あると指摘しました。 JavaScript 言語の実装の詳細をよく理解している場合にのみ、それらの違いを見分けることができます。
最初の書き方 直感に従って、次のように書けると思うかもしれません:
if (!myObj) {
myObj = { }
;
ただし、このコードを実行すると、ブラウザは ReferenceError エラーを直接スローし、操作が中断されます。どうしたの?
ちなみに、myObj が空かどうかを if ステートメントで判定する際には、この変数はまだ存在しないため、エラーが報告されます。以下のように変更すると正常に動作するようになります。
if (!myObj) {
var myObj = { };
}
var を追加してもエラーが出ないのはなぜですか?この場合、if文で判断する時点でmyObjはすでに存在しているのでしょうか?
この質問に答えるには、JavaScript インタプリタがどのように動作するかを知る必要があります。 Javascript 言語は「最初に解析してから実行」です。変数の宣言は解析中にすでに完了しているため、上記のコードは実際には次と同等です:
var myObj;
if (!myObj) {
var myObj = { }; myObj はすでに存在していると判断されるため、エラーは報告されません。これは、var コマンドの「巻き上げ」効果です。 Javascript インタープリターは、var コマンドによって定義された変数のみを「昇格」し、var コマンドを使用せずに直接割り当てられた変数には機能しません。これが、var が追加されていない場合にエラーが報告される理由です。
の 2 番目の書き方 var コマンドに加えて、これを書き換えて正しい結果を得る別の方法があります:
コードをコピー
Window は JavaScript の最上位オブジェクトであり、すべてのグローバル変数はそのプロパティです。したがって、myobj が空であるかどうかを判断することは、window オブジェクトが myobj 属性を持っているかどうかを判断することと同等であるため、myObj が定義されていないために発生する ReferenceError エラーを回避できます。ただし、コードの標準化の観点から、2 行目に var を追加するのが最善です。
コードをコピー
または次のように記述します:
コードをコピー
3 番目の書き方
上記の書き方の欠点は、一部の実行環境 ( V8、Rhino)、ウィンドウはトップレベル オブジェクトではない可能性があります。したがって、次のように書き直すことを検討してください:
コードをコピーします
;
グローバル変数のレベルでは、this キーワードは常にトップレベルの変数を指すため、さまざまな動作環境から独立できます。
4 番目の書き方 ただし、上記の書き方は可読性が低く、ポインタが可変でエラーが発生しやすいため、さらに書き直されます。 🎜>
var global = this; if ( !global.myObj) {
global.myObj = { };
}
トップレベルのオブジェクトを表すためにカスタム変数 global を使用する方がはるかに明確です。
の 5 番目の記述方法 また、typeof 演算子を使用して、myObj が定義されているかどうかを判断することもできます。 if (typeof myObj == "unknown" ) {
var myObj = {};
}
これは、JavaScript オブジェクトが存在するかどうかを確認するために現在最も広く使用されている方法です。
6 番目の書き方
myObj の値は、定義されていても代入されていない場合、そのまま unknown に等しいため、上記の書き方は次のように簡略化できます。 var myObj = { };
}
ここで注意すべき点が 2 つあります。1 つ目は、2 行目の var キーワードを省略することはできません。2 つ目は、unknown が発生することです。ここで比較されるのは、文字列「unknown」ではなく、データ型 unknown であるため、一重引用符または二重引用符が追加されます。
7 番目の書き方
上記の書き方は「完全比較」 (===) の場合にも当てはまります:
var myObj = { } ;
}
8 番目の書き方
JavaScript の言語設計によれば、未定義 == null なので、myObj が null に等しいかどうかを比較できます。
var myObj = { };
}
ただし、実行結果は正しいものの、意味的にはこの判定方法は間違っているので避けるべきです。 null は、null の値が割り当てられた空のオブジェクトを指します。つまり、このオブジェクトには実際に値があります。一方、未定義は、存在しないか、値が割り当てられていないオブジェクトを指します。したがって、ここで使用できるのは「比較演算子」(==) のみです。「完全比較演算子」(===) を使用するとエラーが発生します。
9 番目の書き方
in 演算子を使用して、myObj がトップレベル オブジェクトの属性であるかどうかを判断することもできます:
window.myObj = { };
}
10 番目の書き方
最後に、hasOwnProperty メソッドを使用して、myObj がトップレベル オブジェクトのプロパティであるかどうかを確認します。 :
this.myObj = { };
}
概要
1. 5 番目の書き方を使用することをお勧めします。
2. オブジェクトが存在するかどうかに加えて、オブジェクトが null 値を持つかどうかも判断する必要がある場合は、最初の記述方法を使用することをお勧めします。 3. 特別な事情がない限り、すべての変数は var コマンドを使用して宣言する必要があります。
4. クロスプラットフォームにするために、トップレベルのオブジェクトを表すためにウィンドウを使用しないことをお勧めします。
5. Javascript 言語では、null と未定義は混同されやすいです。両方が関係する可能性がある場合は、「完全比較」演算子 (===) を使用することをお勧めします。