2011-01-27 6 views
26

ECMAScript5のObject.defineProperty機能を使用して、以下のコードを考えてみましょう:IE8の壊れたObject.defineProperty実装の周りの作業

var sayHi = function(){ alert('hi'); }; 
var defineProperty = (typeof Object.defineProperty == 'function'); 
if (defineProperty) Object.defineProperty(Array.prototype,'sayHi',{value:sayHi}); 
else Array.prototype.sayHi = sayHi; 
var a = []; 
a.sayHi(); 

これはChromeと(definePropertyが存在する)のFirefox 4のために働き、そしてそれは、Firefox 3.6で動作します(ここで、defineProperty存在しない)。しかしながら、IE8、only partially supports defineProperty。その結果、Object.definePropertyメソッドが実行されますが、エラーはブラウザに表示されずに失敗し、ページ上の他のすべてのJavaScriptコードの実行が停止します。

よりもIE8の壊れた実装を検出し、回避するためのより良い方法があります:

好奇心のために
if (defineProperty){ 
    try{ Object.defineProperty(Array.prototype,'sayHi',{value:sayHi}); }catch(e){}; 
} 
if (!Array.prototype.sayHi) Array.prototype.sayHi = sayHi; 

は私がするもののブラウザで非可算配列のメソッドを定義するために、私のArraySetMathライブラリでこれを使用しています、これをサポートしています。これは古いブラウザーのための列挙可能なメソッドに置き換えられます。

答えて

22

try/catchを使用した直接機能テストよりも優れた方法はないと思います。これは実際には正確にIEチーム自身がこの最近の記事transitioning to ES5 APIに投稿したものです。

Object.defineProperty({}, 'x', {})Array.prototypeではなく)のようにテストを短縮することはできますが、それはちょっとしたことです。あなたの例は正確な機能をテストします(したがって、誤検出の可能性も低くなります)。私はパッケージにBrowserifyを使用してい

0

私はこの前につまずきました。 try ... catchステートメントを使用しているIMHOはあまりにも抜本的です。より効率的な
何かが条件付きコンパイルを使用することです:

/*@[email protected](@_jscript_version>5.8)if(document.documentMode>8)@*/ 
Object.defineProperty && Object.defineProperty(Array.prototype,'sayHi',{value:sayHi}); 
/*@[email protected]*/ 
0

私は、同じ種類の問題(つまり、IE 8でObject.definePropertyは、他のブラウザとしてDOMだけではなく完全な実装であることを)持っていたが、それポリフィルのためだった。..

Anyhooが、私はその完璧ではないIEを使用していたかどうかを確認「機能」を使用して終わったが、それは私が行うことができるすべてのテストに取り組んでいます:

if (Object.defineProperty && !document.all && document.addEventListener) { 
    Object.defineProperty(Array.prototype,'sayHi',{value:sayHi}); 
} else { 
    Array.prototype.sayHi = sayHi; 
} 

IEとして< = 8 document.addEventListenerはありません。document.allは、W3C標準のMicrosoft独自の拡張機能です。これらの2つのチェックは、IEがバージョン8以下であるかどうかをチェックするのと同じです。

0
Array.prototype.sayHi = function(){ alert('hi'); }; 

try { 
    Object.defineProperty(Array.prototype, 'sayHi', { 
    value: Array.prototype.sayHi 
    }); 
} 
catch(e){}; 
関連する問題