如果我将新属性添加到HTMLElement
的原型中,并将其默认值设置为“{}
”(空对象):
Object.defineProperty(HTMLElement.prototype, 'customObject',
{ configurable: true, enumerable: true, writeable: true, value: {} });
现在我创建一个新的div
(也是HTMLElement
):
var e = document.createElement('div');
我将属性分配给customObject
的{{1}}:
e
如果我发出警告,我会看到所需的值:
e.customObject.prop = "bla";
现在我创建一个新的,不同的alert(e.customObject.prop); // Displays 'bla'.
元素:
div
此var d = document.createElement('div');
现在应该有一个空的d
属性,对吗?
但是,如果我提醒它:
customObject
我得到了这个意想不到的结果:
alert (d.customObject.prop);
为什么?当我创建一个新元素时,它不应该有一个HTMLElement.prototype的“空白”实例吗?
(jsfiddle:http://jsfiddle.net/5pgr38mb/)
修改 我正在寻找将使用深度克隆(cloneNode(true))的解决方案。 含义 - 如果自定义对象在元素 或其任何子元素 上具有属性,则该元素或子元素将在克隆实例中保留其值(这是正常行为“native”HTMLElement属性)。
答案 0 :(得分: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模式非常接近how actual per-element DOM properties are implemented in the Web IDL specification。这里唯一的区别是每个元素的值存储在一个属性中,而不是隐藏的映射。
答案 1 :(得分: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);