在JavaScript中访问__defineGetter __/__ defineSetter__隐藏的属性

Bru*_*rry 5 javascript dom innerhtml prototypejs getter-setter

我正在尝试为该innerHTML属性定义自定义setter .不幸的是,我在定义setter函数后无法访问底层属性:

$('body')[0].__defineSetter__("innerHTML",
  function (val) {
    alert("Setting to: " + val);
    this.innerHTML = val;
});
Run Code Online (Sandbox Code Playgroud)

此片段填充调用堆栈,因为赋值以递归方式调用setter.Apparenly 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);
    }
});
Run Code Online (Sandbox Code Playgroud)

但是,Chrome的情况似乎并非如此,其中getOwnPropertyDescriptor返回未定义innerHTML.在这种情况下,我如何访问底层属性?

奖金问题:我如何确保将来创建的所有对象都有这种特殊innerHTML行为?是否可以使用DOM原型?似乎重载函数不是我需要的.也许有可能重载DOM构造函数并添加一个调用,__defineGetter__/defineProperty但看起来对构造函数的支持并不常见,所以我想知道是否有任何替代方法.

dev*_*os1 1

您所需要的只是一个单独的数据存储属性来存储实际值,就像使用 getter 和 setter 的其他语言一样。您可以使用闭包来隐藏它们。

var _innerHTML = "";

this.__defineSetter__( "innerHTML",
    function (val) {
        alert("Setting to: " + val);
        _innerHTML = val;
    } );

this.__defineGetter__( "innerHTML",
    function () {
        return _innerHTML;
    } );
Run Code Online (Sandbox Code Playgroud)

但是,我发现在现有 DOM 属性上使用 getter 和 setter 通常不起作用,因为这些属性在内部进行了特殊处理。例如,它不适用于valuetext 的属性input。我希望innerHTML能在同一条船上。