在 JavaScript 中访问被 __defineGetter__/__defineSetter__ 隐藏的属性
Posted
技术标签:
【中文标题】在 JavaScript 中访问被 __defineGetter__/__defineSetter__ 隐藏的属性【英文标题】:Accessing properties hidden by __defineGetter__/__defineSetter__ in JavaScript 【发布时间】:2011-08-31 12:32:51 【问题描述】:我正在尝试为 innerhtml
属性定义自定义设置器。不幸的是,在我定义了 setter 函数后,我无法访问底层属性:
$('body')[0].__defineSetter__("innerHTML",
function (val)
alert("Setting to: " + val);
this.innerHTML = val;
);
这个 sn-p 填充调用堆栈,因为赋值递归地调用 setter。
显然innerHTML
已经是 IE8 中的重载属性,您可以简单地保存旧的 get/set 对并在新的属性描述符中使用它。取自 MSDN:
var innerHTMLdescriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
Object.defineProperty(Element.prototype, 'innerHTML',
set: function(htmlVal)
var safeHTML = toStaticHTML(htmlVal);
innerHTMLdescriptor.set.call(this, safeHTML);
);
但是,Chrome 似乎并非如此,其中getOwnPropertyDescriptor
为innerHTML
返回未定义。在这种情况下,如何访问底层属性?
额外问题:如何确保将来创建的所有对象都具有这种特殊的innerHTML
行为?是否可以为此使用 DOM 原型?似乎重载函数不是我在这里需要的。也许可以重载 DOM 构造函数并添加一个调用 __defineGetter__/defineProperty
但看起来对构造函数的支持并不常见,所以我想知道是否有任何替代方法。
【问题讨论】:
不要在实际生产代码中使用 __defineSetter__ - 它是非标准的,可能会排除许多浏览器的用户。 标准等效项是defineProperty
对吗?仍然存在引用隐藏属性的问题...
不,它仍然不是一个真正的标准。您不应该使用它,因为它不包括旧浏览器。当然,如果您正在做一些非关键的事情并且它会优雅地降级,那没关系。但它看起来不像你的情况。
在形式上它似乎是一个标准(ecmascript 5),但是是的,我同意它还没有很好的兼容性。别担心,我不会开发任何你最喜欢的网络应用程序:D
前景不太好。见***.com/questions/2920180/…
【参考方案1】:
您只需要一个单独的数据存储属性来存储实际值,就像其他使用 getter 和 setter 的语言一样。您可以使用闭包将它们隐藏起来。
var _innerHTML = "";
this.__defineSetter__( "innerHTML",
function (val)
alert("Setting to: " + val);
_innerHTML = val;
);
this.__defineGetter__( "innerHTML",
function ()
return _innerHTML;
);
但是,我发现在现有 DOM 属性上使用 getter 和 setter 通常根本不起作用,因为内部对这些属性进行了特殊处理。例如,它不适用于文本 input
的 value
属性。我希望innerHTML
在同一条船上。
【讨论】:
以上是关于在 JavaScript 中访问被 __defineGetter__/__defineSetter__ 隐藏的属性的主要内容,如果未能解决你的问题,请参考以下文章