使用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和Firefox 4(其中defineProperty
存在),适用于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库中使用它来在那些支持它的浏览器中定义不可枚举的数组方法,并回退到旧浏览器的可枚举方法。
答案 0 :(得分:22)
我认为没有比使用try / catch进行直接功能测试更好的方法。这实际上正是IE团队在transitioning to ES5 API最近的帖子中推荐的。
您可以将测试缩短为Object.defineProperty({}, 'x', {})
(而不是使用Array.prototype
),但这是一个小问题;您的示例测试了确切的功能(因此误报的可能性更小)。
答案 1 :(得分:7)
我使用Browserify和npm中的包使用Object.defineProperty进行复数化,然后将其删除。
https://github.com/inexorabletash/polyfill/blob/master/es5.js
答案 2 :(得分:0)
{{1}}
答案 3 :(得分:0)
我遇到了同样的问题(即IE 8中的Object.defineProperty只是DOM而不是其他浏览器的完整实现),但是它适用于polyfill ..
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扩展。这两项检查相当于检查IE是否为版本8或更低版本。
答案 4 :(得分:0)
Array.prototype.sayHi = function(){ alert('hi'); };
try {
Object.defineProperty(Array.prototype, 'sayHi', {
value: Array.prototype.sayHi
});
}
catch(e){};