以下代码演示了 JavaScript 中属性查找的“标准”规则。它创建一个空对象a
,其原型(prototype)包含属性i
。读取 a.i
给出原型(prototype)中的值,但写入 a.i
会在对象本身中创建一个新属性:
function A() {}
A.prototype = { i: 1 }
a = new A();
console.log(a.i, a.hasOwnProperty('i')); // 1 false
a.i = 2
console.log(a.i, a.hasOwnProperty('i')); // 2 true
但是,如果我们在原型(prototype)中有一个 setter,则行为会有所不同。现在,编写 a.i
会调用 setter,而不是直接写入对象:
function A() {}
A.prototype = { set i(value) { this._i = value }, _i: 1 }
a = new A();
console.log(a.i, a.hasOwnProperty('i')); // undefined false
console.log(a._i, a.hasOwnProperty('_i')); // 1 false
a.i = 2
console.log(a.i, a.hasOwnProperty('i')); // undefined false
console.log(a._i, a.hasOwnProperty('_i')); // 2 true
原型(prototype)中 setter 的存在完全改变了写入 a.i
时发生的情况。是否有任何其他语言功能会改变访问属性时发生的情况?具体来说,除了存在 setter 之外,写入总是直接更新对象吗?
最佳答案
一个异常(exception)是,如果您的对象是代理,它允许您拦截对该对象的所有属性调用,并且您可以获得被调用的属性的名称。您还可以控制许多其他行为。所以你可以这样做
const target = {};
const proxyHandler = {
set(target, property, value, receiver) {
//gets called on any setter operation
}
};
const proxy = new Proxy(original, proxyHandler );
这里有更多信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
关于javascript - JavaScript 属性查找规则有哪些异常(exception)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46646653/