1.後方互換性
JavaScriptはECMAScriptの実装です。これらの機能のほとんどはECMAScript 5(ES5)で導入されましたが、市場で十分なシェアを維持している多くの古いブラウザーはこれらの機能をサポートしていません(ECMAScript 5互換性表を参照)。これらの最も顕著なものはIE8です。
通常、ライブラリはネイティブ実装に戻ります。存在しない場合は、独自のポリフィルを使用します。たとえば、AngularJSの実装(angle.js L203-257)を見てみましょう。
function forEach(obj, iterator, context) {
var key;
if (obj) {
if (isFunction(obj)){
for (key in obj) {
// Need to check if hasOwnProperty exists,
// as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
iterator.call(context, obj[key], key);
}
}
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
} else if (isArrayLike(obj)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
} else {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key);
}
}
}
}
return obj;
}
次の行は、forEach
メソッドがオブジェクトに存在するかどうか、およびそれがAngularJSバージョンかどうかを確認します。そうでない場合は、既に指定されている関数(ネイティブバージョン)を使用します。
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
}
2.利便性
ネイティブJavaScript ではArray.prototype.forEach
、のインスタンス専用のメソッドですが、Array
ほとんどのメソッドObject
は反復可能です。
このため、多くのライブラリ作成者は関数を多態的にしています(複数の型を入力として受け入れることができます)。上記のAngularJSコードを使用して、受け入れられる入力を確認しましょう。
機能:
if (isFunction(obj)){
for (key in obj) {
// Need to check if hasOwnProperty exists,
// as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
iterator.call(context, obj[key], key);
}
}
配列(ネイティブforEachサポート付き):
} else if (obj.forEach && obj.forEach !== forEach) {
obj.forEach(iterator, context);
Array(ネイティブforEachサポートなし)、String、HTMLElement、有効な長さプロパティを持つオブジェクトを含む配列のようなオブジェクト:
} else if (isArrayLike(obj)) {
for (key = 0; key < obj.length; key++)
iterator.call(context, obj[key], key);
オブジェクト:
} else {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key);
}
}
}
結論
ご覧のとおり、AngularJSはほとんどのJavaScriptオブジェクトを反復処理しますが、ネイティブ関数と同じように機能しますが、はるかに異なるタイプの入力を受け入れ、ES5関数をライブラリに追加する有効な手段です。レガシーブラウザへ。