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