使用HTMLElement作为自定义函数原型时的奇怪属性行为
Strange attribute behaviour when using HTMLElement as prototype of custom Function
我正在尝试"扩展"(不确定这类扩展的正确术语是什么)一个DOMElement来覆盖某些属性(基本元素)。为此,我动态创建一个函数,其原型是我想要扩展的DOMElement,然后用该函数(扩展元素)实例化一个对象。
当为扩展元素赋值时,预期的结果是在扩展元素中创建具有给定名称的属性,使基本元素保持不变,即使它具有相同名称的属性。使用普通对象作为基元素可以完美地执行此操作,但当使用DOMElement作为基元素时,如果存在同名属性,则会修改基元素(在Chrome和Firefox上。在IE9上,即使试图获取属性值,也会抛出"无效调用对象")。
测试代码:
var base = $("<input type='text' />")[0];
//Plain object example: var base = {value:null}
base.value = "original";
var MyClass = function(){ };
MyClass.prototype = base;
var obj = new MyClass();
obj.value = "modified";
obj.value //"modified" (OK)
base.value //"modified" (WRONG!) - "original" if plain object is used (OK)
应用程序:
我想要做的是创建一个具有重写"value"属性的输入元素的扩展实例。这将允许将此对象传递给验证器插件,该插件将使用重写的值来运行其所有验证规则,并且在出现任何错误的情况下,原始对象将保持不变,扩展对象将保留验证器所做的所有修改。
由于IE中可能出现无法解决的异常,我们不打算进一步应用这种方法,但我仍然对这种奇怪的行为很感兴趣。
问题可能是什么:
我认为这种行为源于这样一个事实,即DOMElement属性和函数不是纯粹的Javascript,而是一个浏览器接口的实现。在这种情况下,这样会影响原型"继承"的工作方式,使值的本地setter实现起作用,而不是在扩展对象上创建属性。(IE中抛出的异常可以支持这一点,该异常表示我正试图从非本机元素访问本机函数/属性)。
这似乎已经完成了任务:
var base = $("<input type='text' />")[0];
base.value = "original";
function MyClass() {
Object.defineProperty(this, "value", {
value: null,
configurable: true,
enumerable: true,
writable: true
});
}
MyClass.prototype = base;
var obj = new MyClass();
obj.value = "modified";
console.log(obj.value); //"modified" (OK)
console.log(base.value); //"original" (OK)
问题是obj
实例从来没有自己的value
:它总是委托给原型的setter,即HTMLInputElement.prototype.value
。因此,obj
的所有实例都将共享相同的value
属性。
换句话说,说obj.value = "modified"
和说Object.getPrototypeOf(obj).value = "modified"
是一样的,当然还有Object.getPrototypeOf(obj) === base
。
我的第一次尝试是为MyClass
提供它自己的每个实例value
属性,如下所示:
function MyClass() {
this.value = null;
}
但这实际上并没有达到我们想要的效果,因为this.value
只是引用了原型的value
:我们没有创建新的属性;我们正在设置现有的。Object.defineProperty
向运行时明确表示,我们想要创建一个新的,所以这就成功了。
- 使用带有自定义对象作为属性的jQuery.extend时出现意外行为
- CSS根据属性的可用性有条件地应用样式
- 使用 jQuery 检查文本可见性 .包含代码的行为不符合预期
- 如何在 Safari 中获取下载属性行为
- 当我添加命名属性时,为什么数组会有这种行为
- 如何使用ES6在Ember中声明可观察性或计算属性
- 范围属性可见性
- 使用jquery的单个类属性可见性
- css 可见性属性和 javascript setTimeout 方法出错
- map.getBounds() 奇怪的行为(未捕获的类型错误:无法读取未定义的属性“getNorthEast”)
- 在 HTML 定位点中指定“语言”属性是否会更改事件行为
- 角度 js 服务/工厂属性行为
- 使用“=”测试相等性时“if”语句的意外行为
- 淘汰基实体属性可用性令人困惑
- 指令范围属性注入行为
- 复制对象后删除对象属性时出现奇怪的行为
- 输入元素模式属性的行为不象regex
- Javascript对象私有属性的行为就像公共的一样
- 如果在使用之前访问了Object.defineProperty定义的属性,为什么该属性的行为会发生变化
- jQuery在分配“选定”属性时行为不一致