JavaScript引擎如何在具有原型的对象上设置属性,并为该属性设置一个setter
How do javascript engines set properties on objects that have prototypes with a setter for that property?
我总是觉得,当对对象调用[[set]]
(或者[[put]]
?(时,引擎总是将属性分配给(或尝试(给该对象,而不管它的原型如何。
但是今天当我尝试这个
parent={
set num(v){
alert();
}
}
obj=Object.create(parent);
obj.num=123;
它调用了 setter,那么当引擎设置属性时到底会发生什么?它是否遍历原型链以首先检查它是否有任何二传手?
引擎执行它一贯执行的操作,即首先在实例上查找属性,如果不在实例上查找属性,则在原型链中查找属性。如果属性(无论在何处找到且以何种方式定义(都是使用资源库定义的,则执行资源库。在您的情况下,它会在原型父级中找到属性,并执行资源库,显示警报。实际上什么都没有设置。(当然,如果属性不是使用资源库定义的,则在实例上设置值。
如果要在实例本身上实际创建具有相同名称的属性,可以使用defineProperty
(或要Object.create
的第二个参数(来实现。此属性将在原型上以相同的名称"隐藏"(隐藏(属性。下次尝试设置该属性时,引擎将在实例上找到该属性,并将其设置在那里(除非您在实例上定义的属性也具有 setter,在这种情况下,将调用该 setter(。
请注意,二传手本身不进行设置。无论你想做什么设置,你都必须自己做。例如,您可能希望通过说 this._num = v
来设置代理属性,例如 _num
。显然,this
这里是实例 - 即使 setter 是在原型上定义的 - 因此 _num
属性将位于实例上。如果你尝试在二传手内部执行this.num = v
,你最终会得到一个无限循环,因为这会再次调用同一个二传手。 num
不能同时是基于getter/setter的属性和正常值的属性。
请考虑以下事项:
parent = { set num(v) { alert(v); } };
obj = Object.create(parent);
obj.num = 44; // alert
obj2 = Object.create(parent, { num: { value: 55 } });
obj2.num = 99 // proto ignored, no alert, simple assignment
- 将属性设置为未定义时未通知观察者
- 是否有任何内置方法可以更改JavaScript对象'的属性设置为某个值
- 附加'沙箱'属性设置为动态创建的iframe以停止重定向
- 如何将按钮的数据属性设置为输入[type=text]中设置的任何值
- 在jquery中,从同一对象的属性设置输入字段和标签的正确方法是什么
- 当可见属性设置为 false 时,使用 JavaScript 删除空格
- 无法使用 Snap.SVG将“填充”属性设置为“继承”
- 使用jQuery为属性设置新值
- 是否可以通过属性's值,并将属性设置为parentNode
- 如何使用按钮的jsp点击事件将属性设置为struts-bean
- 在ember.js记录上使用toJSON,将其中一个属性设置为null
- javascript函数属性设置器中的延迟
- 添加“;选中'属性设置为jquery中的复选框
- jQuery/JavaScript按属性设置数组
- Dojo.将JSon中的属性设置为HTML属性
- 将class属性设置为元素不适用于javascript和jquery
- 将属性设置为对对象的引用
- 如何将显示属性设置为与内联!重要的
- jQuery-根据HTML属性设置CSS维度
- 为什么我不能在 JavaScript 中将对象属性设置为空字符串