2011-01-27 60 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和Firefox 4(defineProperty存在),它適用於火狐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),但這是一個小小的狡辯;你的例子測試確切的功能(所以誤報率更低)。

0

我以前無意中發現了這一點。恕我直言,使用try ... catch語句太激烈了。
東西更有效的辦法是使用條件編譯:

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

我有同樣的此類問題(即Object.defineProperty在IE 8是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.all是W3C標準的專有Microsoft擴展。這兩項檢查相當於檢查IE是否爲版本8或更低版本。

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

try { 
    Object.defineProperty(Array.prototype, 'sayHi', { 
    value: Array.prototype.sayHi 
    }); 
} 
catch(e){};