26

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ライブラリでこれを使用して、これをサポートするブラウザーで列挙不可能な配列メソッドを定義し、古いブラウザーの列挙可能なメソッドにフォールバックしています。

4

5 に答える 5

22

try/catchを使用した直接機能テストよりも優れた方法はないと思います。これは、実際には、ES5APIへの移行に関するこの最近の投稿でIEチーム自体が推奨していることとまったく同じです。

Object.defineProperty({}, 'x', {})テストを(を使用する代わりに)のようなものに短縮することもできますがArray.prototype、それはちょっとした問題です。この例では、正確な機能をテストします(したがって、誤検知の可能性が低くなります)。

于 2011-02-01T20:44:22.233 に答える
7

Object.definePropertyを使用するnpmからのパッケージpluralizeでBrowserifyを使用しており、これをにドロップしました。

https://github.com/inexorabletash/polyfill/blob/master/es5.js

于 2014-03-12T03:26:11.390 に答える
0

私は前にこれにつまずいた。try…catchステートメントを使用するIMHOは、あまりにも徹底的です。
より効率的な方法は、条件付きコンパイルを使用することです。

/*@cc_on@if(@_jscript_version>5.8)if(document.documentMode>8)@*/
Object.defineProperty && Object.defineProperty(Array.prototype,'sayHi',{value:sayHi});
/*@end@*/ 
于 2017-04-04T18:40:22.867 に答える
0

私は同じ種類の問題を抱えていました(つまり、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.addEventListenerdocument.allW3C標準に対する独自のMicrosoft拡張機能です。これらの2つのチェックは、IEがバージョン8以下であるかどうかをチェックするのと同じです。

于 2017-07-01T19:11:58.747 に答える
0
Array.prototype.sayHi = function(){ alert('hi'); };

try {
  Object.defineProperty(Array.prototype, 'sayHi', {
    value: Array.prototype.sayHi
  });
}
catch(e){};
于 2017-08-18T13:57:00.133 に答える