オンラインソースコードを見ると、いくつかのソースファイルの先頭でこれに遭遇しました。
var FOO = FOO || {};
FOO.Bar = …;
しかし、私は何がわからない || {}ができるのません。
私は知っている{}と等しいnew Object()と思います||は「すでに存在する場合はその値を使用し、それ以外の場合は新しいオブジェクトを使用する」のようなもののためます。
これがソースファイルの上部に表示されるのはなぜですか?
オンラインソースコードを見ると、いくつかのソースファイルの先頭でこれに遭遇しました。
var FOO = FOO || {};
FOO.Bar = …;
しかし、私は何がわからない || {}ができるのません。
私は知っている{}と等しいnew Object()と思います||は「すでに存在する場合はその値を使用し、それ以外の場合は新しいオブジェクトを使用する」のようなもののためます。
これがソースファイルの上部に表示されるのはなぜですか?
回答:
の意図に関するあなたの推測 || {}はかなり近いです。
ファイルの上部に表示されるこの特定のパターンは、名前空間を作成するために使用されます、つまり、グローバルオブジェクトを過度に汚染することなく関数と変数を作成できる名前付きオブジェクトます。
理由なぜそれが使われていますが、あなたが2つ(またはそれ以上)のファイルを持っている場合はそうあることです:
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}
そして
var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}
それはその後、問題二つのファイルがロードされるためには、あなたはまだ取得していません、どちらも共有し、同じ名前空間のfunc1とfunc2正しく内で定義されましたMY_NAMESPACEオブジェクトます。
最初にロードされたファイルにより初期オブジェクトが作成され、MY_NAMESPACEその後ロードされたファイルによりオブジェクトが拡張されます。
便利なことに、これにより、同じ名前空間を共有するスクリプトの非同期読み込みが可能になり、ページの読み込み時間を改善できます。<script>タグにdefer属性セットがある場合、タグが解釈される順序がわからないため、上記で説明したように、この問題も修正されます。
||あなたはオプションの引数を提供したいとデフォルトにそれらを初期化するときに提供されていない場合にも本当に便利です:function foo(arg1, optarg1, optarg2) { optarg1 = optarg1 || 'default value 1'; optarg2 = optart2 || 'defalt value 2';}
||演算子がundefinedから判断できないため、偽の値も有効falseyです。
var AEROTWIST = AEROTWIST || {};
基本的に、この行はAEROTWIST変数をAEROTWIST設定するか、空のオブジェクトに設定することを示しています。
ダブルパイプ ||はORステートメントであり、ORの2番目の部分は、最初の部分がfalseを返した場合にのみ実行されます。
したがって、AEROTWISTすでに値がある場合は、その値として保持されますが、まだ設定されていない場合は、空のオブジェクトとして設定されます。
これは基本的にこれを言うのと同じです:
if(!AEROTWIST) {var AEROTWIST={};}
お役に立てば幸いです。
||のもう1つの一般的な用途 未定義の関数パラメーターのデフォルト値も設定します。
function display(a) {
a = a || 'default'; // here we set the default value of a to be 'default'
console.log(a);
}
// we call display without providing a parameter
display(); // this will log 'default'
display('test'); // this will log 'test' to the console
他のプログラミングにおける同等のものは通常、次のとおりです。
function display(a = 'default') {
// ...
}
varの前にa、aとして関数の実行コンテキストに入り、仮パラメータので、それは既に宣言されています、。
var FOO = FOO || {};カバーする2つの主要な部分があります。
#1オーバーライドの防止
コードを複数のファイルに分割していて、同僚がと呼ばれるオブジェクトで作業しているとしFOOます。次に、誰かがすでにFOO機能を定義して機能を割り当てているというケースにつながる可能性がありskateboardます。それがすでに存在するかどうかを確認していなかった場合は、それをオーバーライドします。
問題のあるケース:
// Definition of co-worker "Bart" in "bart.js"
var FOO = {};
FOO.skateboard = function() {
alert('I like skateboarding!');
};
// Definition of co-worker "Homer" in "homer.js"
var FOO = {};
FOO.donut = function() {
alert('I like donuts!');
};
この場合、Homerが新しいオブジェクトを定義する(したがって、Bartからの既存のオブジェクトをオーバーライドする)ため、HTMLの後にskateboardJavaScriptファイルをロードすると、関数のみが認識され、関数についてのみ認識されます。homer.jsbart.jsFOOdonut
したがって、var FOO = FOO || {};「FOOがFOO(既に存在する場合)または新しい空のオブジェクト(FOOがまだ存在しない場合)に割り当てられることを意味するを使用する必要があります。
解決:
var FOO = FOO || {};
// Definition of co-worker Bart in bart.js
FOO.skateboard = function() {
alert('I like skateboarding!');
};
// Definition of co-worker Homer in homer.js
var FOO = FOO || {};
FOO.donut = function() {
alert('I like donuts!');
};
バートとホーマーは、今の有無をチェックしているのでFOO、彼らは彼らのメソッドを定義する前に、あなたは読み込むことができますbart.jsし、homer.js(彼らは別の名前を持っている場合)、互いのメソッドをオーバーライドすることなく、任意の順序インチ したがって、常にFOOメソッドskateboardとdonut(Yay!)を持つオブジェクトを取得します。
#2新しいオブジェクトを定義する
最初の例を読んだことがあれば、すでにの目的は何ですか|| {}。
既存のFOOオブジェクトがない場合、ORケースがアクティブになり、新しいオブジェクトが作成されるため、それに関数を割り当てることができます。お気に入り:
var FOO = {};
FOO.skateboard = function() {
alert('I like skateboarding!');
};
||オペレータは、2つの値をとります。
a || b
aが真実なら、それは戻りaます。それ以外の場合は、が返されbます。
falsy値はnull、undefined、0、""、NaNとfalse。真実の値は他のすべてです。
そのaため、設定されていない場合(そうである場合undefined)は戻りbます。
||JS(およびPerl)とC、C ++、およびJavaのバージョンの唯一の違いは、JSが結果をブール値にキャストしないことです。それはまだ論理演算子です。