【问题标题】:What exceptions are there to the JavaScript property lookup rules?JavaScript 属性查找规则有哪些例外?
【发布时间】:2017-10-09 12:37:54
【问题描述】:

以下代码演示了 JavaScript 中属性查找的“标准”规则。它创建一个空对象a,其原型包含一个属性i。读取a.i 会给出原型的值,但写入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

但是,如果我们在原型中有一个 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

原型中设置器的存在完全改变了写入a.i 时发生的情况。是否有任何其他语言功能可以改变访问属性时发生的情况?具体来说,除了存在 setter 之外,写入是否总是直接更新对象?

【问题讨论】:

  • 原型对象上的 getter(或纯数据属性)的存在也“完全改变”了访问属性时发生的情况。我不知道你为什么称它为“例外”。

标签: javascript inheritance prototype getter-setter


【解决方案1】:

一个例外是,如果您的对象是代理,则可以拦截对对象的所有属性调用,并获得被调用属性的名称。您也可以控制许多其他行为。所以你可以做

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

【讨论】:

    猜你喜欢
    • 2017-01-03
    • 2017-05-15
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多