原型中的 Setter 属性与数据属性

有人可以解释以下行为吗?


var p = {

  name: "John",

  set age(value) {

    console.log("Age set to", value);

  }

}


var obj = {};

Object.setPrototypeOf(obj, p);


obj.name = "Jill"; // Doesn't alter the name on prototype, creates a new property on obj

obj.age = 22; // Calls the setter on prototype


为什么分配 to 会age调用原型上的 setter,而分配 toname会在 上创建新属性obj?


POPMUISE
浏览 120回答 2
2回答

凤凰求蛊

这就是 JavaScript 的工作原理。当=用于分配属性时,引擎将在对象的原型链中查找第一个与属性名称匹配的属性描述符。如果找到这样的描述符,并且该描述符是访问器(即,具有 setter 和/或 getter),则将调用该 setter。否则,如果描述符是数据描述符,则没有 setter,新值将分配给实例自己的属性。断言:IsPropertyKey(P) 为 true。如果 ownDesc 未定义,则将 ownDesc 设置为 PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }。返回 ?父级。[[设置]](P、V、接收器)。这就是递归调用。`ownDesc` 设置为包含此属性名称的描述符的第一个祖先。让父母成为?O.[[GetPrototypeOf]]()。如果父级不为空,则别的,如果 IsDataDescriptor(ownDesc) 为 true,则断言:接收者当前没有属性 P。返回 ?CreateDataProperty(接收器,P,V)。如果 IsAccessorDescriptor(existingDescriptor) 为 true,则返回 false。如果existingDescriptor.[[Writable]]为假,则返回假。令 valueDesc 为 PropertyDescriptor { [[Value]]: V }。返回 ?接收者。[[DefineOwnProperty]](P, valueDesc)。使用数据描述符,实例(即“接收器”)会获取分配给它的新值,无论描述符在原型链中的哪个位置找到。如果 ownDesc.[[Writable]] 为 false,则返回 false。如果 Type(Receiver) 不是 Object,则返回 false。让现有描述符是?接收者。[[GetOwnProperty]](P)。如果existingDescriptor不是未定义的,那么别的,断言:IsAccessorDescriptor(ownDesc) 为 true。设 setter 为 ownDesc.[[Set]]。如果 setter 未定义,则返回 false。履行 ?呼叫(二发手、接发手、“V”)。否则,调用 setter。返回真。

人到中年有点甜

当您分配给属性时,它首先在原型链中搜索 setter。如果找到 setter,则简单地执行它。如果没有找到 setter,则会在对象本身中创建或更新普通属性。分配属性永远不会单独分配给继承的属性(setter 可以这样做)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript