Javascript for inの欠陥まとめ


Javascript for inの欠陥まとめ
for in文は、オブジェクトの属性(メンバー)を列挙するために使用されます。以下の通りです。

var obj = { name:"jack",
   getName:function(){return this.name}
};
//  name,getName  
for(var atr in obj) {
  alert(atr);
}
注意しましたか?Objを出力していないtoString、valueOfなどの内蔵属性(または内蔵メンバー、隠し属性と事前定義属性)です。for inは、オブジェクトの表示メンバー(カスタムメンバー)を列挙するために使用されます。
内蔵属性を書き直したら、次にObjのtoStringを書き直します。

var obj = {name:"jack",
   getName:function(){return this.name},
   toString:function(){return "I'm jack."}
}
for(var atr in obj) {
  alert(atr);
}
何を出力しますか?
1、IE 6/7/8の下でtoStringを書き換えていないのと同じで、依然としてnameだけを出力して、getName
2、IE 9/Firefox/Chrome/Opera/Safariではname、get Name、tostringを出力します。 
内蔵するプロトタイプに属性/方法を追加すれば、for inの場合も遍歴できます。

Object.prototype.clone = function() {}
var obj = {
  name: 'jack',
  age: 33
}
// name, age, clone
for (var n in obj) {
  alert(n)
}
Object.prototypeにメソッドcloneを追加しました。for inではすべてのブラウザにcloneが表示されます。
これはまだなんでもないかもしれませんが、内蔵のコンストラクタの原型を拡張することを勧めないからです。これもProttype.jsが没落する原因の一つです。jQueryとUnderscoreは原型から拡張していません。前者はjQueryの対象に文章を作ります。後者は思い切ってすべての方法をアンダーラインにかけます。
しかし、ES 5または後続のバージョンに対応するために、ES 5がサポートされていないブラウザ(IE 6/7/8)で内蔵ビルダーの原型を拡張する場合があります。この場合、for inは各ブラウザで異なります。次のとおりです

if (!Function.prototype.bind) {
  Function.prototype.bind = function(scope) {
    var fn = this
    return function () {
      fn.apply(scope, arguments)
    }
  }
}
function greet(name) { 
  alert(this.greet + ', ' + name)
}
for (var n in greet) {
  alert(n)
}
IE 6/7/8はビットを出力していますが、他のブラウザはありません。現代のブラウザの中でビッドは生のサポートで、for inが足りないので、IE 6/7/8はFuntion.prototypeにbindを追加しました。
まとめ:ブラウザをまたぐデザインでは、for inに依存してオブジェクトのメンバー名を取得することはできません。普通はハスOwnPropertyを使って判断します。
読んでくれてありがとうございます。みなさんのご協力をお願いします。ありがとうございます。