ECMAScript5の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およびFirefox4(defineProperty
が存在する場合)で機能し、Firefox 3.6(defineProperty
が存在しない場合)で機能します。ただし、IE8。 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 ライブラリで使用して、これをサポートするブラウザで列挙不可能な配列メソッドを定義し、列挙可能なメソッドへのフォールバックを使用しています古いブラウザ。
Try/catchを使用した直接機能テストよりも優れた方法はないと思います。これは実際には、IEチーム自体が ES5 APIへの移行 に関するこの最近の投稿で推奨していることです。
テストをObject.defineProperty({}, 'x', {})
のようなものに短縮することができます(Array.prototype
を使用する代わりに)が、それはちょっとした問題です。この例では、正確な機能をテストします(したがって、誤検知の可能性が低くなります)。
Object.definePropertyを使用するnpmからの複数のパッケージでBrowserifyを使用しており、これをにドロップしました。
https://github.com/inexorabletash/polyfill/blob/master/es5.js
Array.prototype.sayHi = function(){ alert('hi'); };
try {
Object.defineProperty(Array.prototype, 'sayHi', {
value: Array.prototype.sayHi
});
}
catch(e){};
私は前にこれにつまずいた。 try…catchステートメントを使用するIMHOは、あまりにも徹底的です。
より効率的な方法は、条件付きコンパイルを使用することです。
/*@cc_on@if(@_jscript_version>5.8)if(document.documentMode>8)@*/
Object.defineProperty && Object.defineProperty(Array.prototype,'sayHi',{value:sayHi});
/*@end@*/
同じ種類の問題がありました(つまり、IE 8のObject.definePropertyはDOMのみであり、他のブラウザーのように完全な実装ではありません)が、それはポリフィル用でした。
とにかく、私は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以下であるかどうかのチェックと同等です。