【问题标题】:How to overwrite getter function on HTMLElement prototype如何覆盖 HTMLElement 原型上的 getter 函数
【发布时间】:2014-05-23 19:14:05
【问题描述】:

由于Object.__defineGetter__() 已被弃用,我试图使用Object.defineProperty() 覆盖HTMLSpanElement.prototype.offsetWidth 上的getter 函数,这样所有<span> 元素在访问offsetWidth 属性时都将返回相同的值。

这在 Firefox 28 和 IE 11 中工作得非常好,但在 Chrome 33 和 34 中(也许其他版本也是如此,我只尝试了这两个)defineProperty() 似乎无法覆盖对象原型的 getter。

这是我的代码,HTML:

<span id="testspan">The quick brown fox</span>

Javascript:

Object.defineProperty(HTMLSpanElement.prototype, "offsetWidth", {
    get: function(){return 5;},
    });

var x = document.getElementById("testspan");
window.alert( x.offsetWidth );

因此,每当访问 span 对象的 offsetWidth 时,它应该返回 5。在 Firefox 28 和 IE11 中它可以正常工作。但在 Chrome 33 和 34 中,它返回 span 元素的实际宽度,在本例中为 126。根据 ECMA-262 v5 规范(相关章节 here),假设我解释正确,我 应该 能够为原型重新定义 getter 和 setter。我错过了什么吗?有人对 Chrome 34 有任何解决方法/黑客吗?

在 JSFiddle here 上试试。如果您都安装了 Chrome 和 Firefox,请在 Chrome 和 Firefox 中尝试。

here 提出了类似的问题,尽管 Scimonster 的建议在 Chrome 34 中不起作用。

【问题讨论】:

  • 在链接到 [谢谢!] 的问题中有一个编辑,从每个对象中删除 offsetWidth 属性会达到目的 - 这是我能找到的最佳解决方案。 (强制 Chrome 在原型链中查找属性)

标签: javascript compatibility


【解决方案1】:

修改属性

当属性已经存在时,Object.defineProperty() 会尝试根据描述符中的值和对象的当前配置来修改属性。如果旧描述符将其可配置属性设置为 false(该属性被称为“不可配置”),则除可写之外的任何属性都不能更改。在这种情况下,也无法在数据和访问器属性类型之间来回切换。

如此处所述:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

是的,从实例中删除 offsetWidth 将强制原型检查并返回 5 :)

【讨论】:

    猜你喜欢
    • 2020-08-16
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-28
    • 2014-03-17
    • 1970-01-01
    相关资源
    最近更新 更多