1

如果我向 的原型添加一个新属性HTMLElement,并且其默认值为 ' {}'(一个空对象):

Object.defineProperty(HTMLElement.prototype, 'customObject', 
{ configurable: true, enumerable: true, writeable: true, value: {} });

现在我创建一个新的div(也是一个HTMLElement):

var e = document.createElement('div');

customObject我为of分配了一个属性e

e.customObject.prop = "bla";

如果我提醒它,我会看到所需的值:

alert(e.customObject.prop); // Displays 'bla'.

现在我创建一个新的、不同的div元素:

var d = document.createElement('div');

d现在应该有一个空customObject属性,对吧?

但是,如果我提醒它:

alert (d.customObject.prop);

我得到了这个意想不到的结果:

bla

怎么来的?当我创建一个新元素时,它不应该有一个 HTMLElement.prototype 的“空白”实例吗?

(jsfiddle:http: //jsfiddle.net/5pgr38mb/

编辑: 我正在寻找一种适用于深度克隆的解决方案 cloneNode(true))。含义 - 如果自定义对象在元素或其任何子项上具有属性,则该元素或子项将在克隆实例中保留其值(这是“本机”HTMLElement 属性的正常行为)。

4

2 回答 2

3

我可能会使用一个原型 getter,它在调用时在实例上创建一个新的对象属性:

Object.defineProperty(HTMLElement.prototype, 'customObject', {
    enumerable: true,
    get: function() {
        if(this.__thisCustomObject === undefined) {
            this.__thisCustomObject = {};
            // or non-enumerable with:
            //    Object.defineProperty(this, '__thisCustomObject', {
            //        enumerable: false,
            //        value: {}
            //    };
        }
        return this.__thisCustomObject;
    },
    set: function(val) {
        this.__thisCustomObject = val;
    }
});

这样,每当您customObject第一次请求对象时,它都会创建一个新对象并将其存储在该对象的__thisCustomObject属性中。然后,所有未来customObject使用该元素__thisCustomObject属性的请求。

请注意,这是一种 getter-setter 模式,非常接近于Web IDL 规范中实际每个元素的 DOM 属性的实现方式。这里唯一的区别是每个元素的值存储在属性中,而不是隐藏映射中。

于 2014-12-05T19:10:41.637 回答
1

您可以覆盖该document.createElement功能。只需打开控制台(在大多数浏览器中为 F12)并单击运行即可查看此代码的结果。

document.createElement = (function () {
    var reference = document.createElement;
    return function (name) {
        var e = reference.call(document, name);
        e.customObject = {
            configurable: true,
            enumerable: true,
            writeable: true,
            value: {}
        };
        return e;
    };
}());

var e = document.createElement('div');
e.customObject.prop = "bla";
console.log(e.customObject.prop);
var d = document.createElement('div');
console.log(d.customObject.prop);

于 2014-12-05T19:06:47.910 回答