JavaScript の in の欠陥の概要
for in ステートメントは、次のようにオブジェクトのプロパティ (メンバー) をリストするために使用されます
var obj = { name:"jack", getName:function(){return this.name} }; //输出name,getName for(var atr in obj) { alert(atr); }
obj の toString、valueOf、およびその他の組み込みプロパティ (またはビルドされたもの) に気づきましたか? -in メンバー、非表示のプロパティ) は出力されず、事前定義されたプロパティ)。つまり、 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. IE6/7/8 では、toString を書き換えない場合と同じです。
2. IE9/Firefox/Chrome/Opera/Safari では、name を出力します。 、 toString.
指定された場合、組み込みプロトタイプは属性/メソッドを追加し、for in の場合もトラバース可能です。
Object.prototype.clone = function() {} var obj = { name: 'jack', age: 33 } // name, age, clone for (var n in obj) { alert(n) }
メソッド clone が Object.prototype に追加され、for in の場合、すべてのブラウザーで clone が表示されます。
組み込みコンストラクターのプロトタイプを拡張することは一般に推奨されていないため、これは大したことではないかもしれませんが、これが Prototype.js の衰退の理由の 1 つでもあります。 jQuery と Underscore は自己プロトタイプを拡張しません。前者は jQuery オブジェクトについて大騒ぎしますが、後者は単にアンダースコアの下ですべてのメソッドをハングします。
ただし、ES5 以降のバージョンと互換性を持たせるために、ES5 をサポートしていないブラウザー (IE6/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) }
IE6/7/8 の出力はバインドされますが、他のブラウザーはバインドされません。最新のブラウザではバインドがネイティブにサポートされており、for in は使用できないため、IE6/7/8 では Function.prototype にバインドを追加します。
要約すると: クロスブラウザーの設計では、オブジェクトのメンバー名を取得するために for in に依存することはできません。通常、hasOwnProperty を使用して判断します。
読んでいただきありがとうございます、お役に立てれば幸いです、このサイトをサポートしていただきありがとうございます!
Javascript for in の欠陥概要に関連するその他の記事については、PHP 中国語 Web サイトに注目してください。