17

この構造が何を意味するのかはわかりませんが、何度か見たことがあります。以下の例は、別のスタック オーバーフローの質問からのものです。最初の「または」構造自体を解釈する方法がわかりません。

Object.keys = Object.keys || (function () {
  var hasOwnProperty = Object.prototype.hasOwnProperty,
      hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
      DontEnums = [ 
          'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
          'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
      ],
      DontEnumsLength = DontEnums.length;
  //etc...
});
4

4 に答える 4

20

a = a || function(){...}は、Javascript で非常に一般的なイディオムです。これは、Javascript に固有のものではありませんが、まだ慣れていない可能性のある 2 つの概念に依存しています。

1.オペレーターの短絡

演算子の短絡[wikipedia]は、不要な評価を防ぐために考案されたコンパイラの最適化です。

これを実証するために、人が 10 代であるかどうか、つまり、年齢が 13 歳から 19 歳の間かどうかを判断したいとします。

var isTeenager = person.age >= 13 && person.age <= 19;

ここで、コードが実行され、その人物が 13 歳未満であることが判明したとします。最初の条件が評価され、false が返されます。&&プログラムは演算子の左辺が であることを認識し、 に評価するには両側が である必要がfalseあるため、右辺を評価しても無意味であることがわかります。&&truetrue

言い換えれば、プログラムは、その人物の年齢が 13 歳以下であることを確認したので、その人物が 10 代ではないことをすでに認識しており、19 歳未満であるかどうかは気にしません。

同じ種類の原則が||オペレーターにも当てはまります。ある人が無料でバスに乗れるかどうか、つまり、その人が 70 歳以上か障害者かどうかを知りたいとします。

var canRideFree = person.age >= 70 || isHandicapped(person);

その人が 70 歳を超えている場合、プログラムはその人が無料で乗れることを既に認識しています。この時点で、プログラムは彼が障害を持っているかどうかを気にしないため、isHandicapped関数の呼び出しを評価しません。一方、その人が 70 歳未満の場合は、戻り値canRideFreeに設定されisHandicappedます。

2.真偽値

真偽の値[ランダムな人のブログ]は、オブジェクトのブール値の評価です。Javascript では、すべてのオブジェクトが「真」または「偽」の値に評価されます。

その値が次のいずれかである場合、式は「偽」です。

false, null, undefined, 0, "", NaN

他のすべては真実です。

人々は、null または未定義の変数が に評価されるという事実を利用しますfalse。これは、変数が存在するかどうかを非常に簡単に確認できることを意味します。

if (a) { /* a exists and is not a falsy value */ }

知っていることを組み合わせる

演算子は||短絡し、評価する最後の式の値を返します。この原則は、次の 1 つのステートメントで真実性と組み合わされています。

Object.keys = Object.keys || function() {...}

が true の場合Object.keys、評価されてそれ自体に割り当てられます。それ以外の場合はObject.keys、関数に割り当てられます。これは、値がすでに存在するかどうかを確認し、存在しない場合は別のものに割り当てるための Javascript の非常に一般的なイディオムです。

C# など、真実性を持たない他の一部の言語には、同様の目的を持つnull 合体演算子[MSDN]があります。

object Value = PossiblyNullValue ?? ValueIfNull;

このコードでValueは、 null でない限り に割り当てられPossiblyNullValueます。null の場合は に割り当てられValueIfNullます。

tl;dr [ウィキペディア]

上で私が言ったことをわざわざ読まなかった場合、知っておく必要があるのは、a = a || function() {...}基本的にこのコードが何をするかということだけです:

if (exists(Object.keys)) {
  Object.keys = Object.keys;
} else { 
  Object.keys = function() {...};
}

function exists(obj) {
  return typeof obj !== "undefined" && 
         obj !== null && 
         obj !== false &&
         obj !== 0 &&
         obj !== "" &&
         !isNaN(obj);
}
于 2011-08-15T18:56:50.280 に答える
2

私が知る限り、そのコードは、関数Object.keysがまだ定義されていない場合 (または false の場合) を定義しようとします。の左側の関数が関数に||なりますObject.keys

「私が言えることから」と言った理由は、コード スニペット全体を投稿していないからです。だけではなく、||読み取り後のコードに注意してください。作成者が関数を自己呼び出しに設定している可能性があります。(function(){function(){

関数定義の後に が表示})()されている場合、関数の戻り値は に格納されていObject.keysます。そうでない場合は、関数自体がそこに格納されます。

于 2011-08-15T18:56:44.137 に答える