javascript属性查找先查自有属性再沿原型链向上,属性描述符仅对当前对象定义的属性生效,不影响原型链同名属性;写入时若原型属性只读则在实例上新建自有属性。

JavaScript 中属性访问时,先查自有属性,再沿原型链向上查找;而属性描述符(如 configurable、enumerable、writable、value 或 get/set)只对**当前对象上定义的属性生效**,不影响原型链上的同名属性行为。
属性查找顺序:从实例到原型链顶端
当读取 obj.prop 时,JS 引擎按以下顺序搜索:
- 检查
obj自身是否含有该属性(无论是否可枚举、是否为访问器) - 如果没有,继续查找
Object.getPrototypeOf(obj)(即obj.__proto__)上的同名属性 - 逐级向上,直到原型为
null(如Object.prototype的原型) - 全程不考虑属性描述符的
enumerable或configurable状态——只要属性存在且没被删除,就会被找到
属性描述符只约束“本层”定义的属性
描述符是属性的元信息,绑定在**具体对象的某个键上**,不会被继承或影响原型链上的同名属性:
-
Object.defineProperty(obj, 'x', { writable: false })→ 只锁住obj.x的赋值,不影响obj.__proto__.x - 若
obj自身没有prop,但原型上有get prop(),那么读取obj.prop触发的是原型上的 getter,与obj的描述符无关 - 用
delete obj.prop只能删除obj自身的属性,即使它不可配置(configurable: false),也不会影响原型链查找
写入属性时的特殊规则:可能创建自有属性
给 obj.prop = value 赋值时,行为取决于属性是否存在及描述符设置:
- 如果
obj自身已有prop且writable: false(且非严格模式),赋值静默失败;严格模式报错 - 如果
obj自身没有prop,但原型链上有prop:
– 若原型上的prop是访问器(get/set),则触发 setter
– 若原型上的prop是数据属性(value),且writable: true,则直接修改原型上的值(注意:这会影响所有共享该原型的对象)
– 若原型上的prop是只读数据属性(writable: false),则在obj上**新建一个同名自有属性**并赋值(即屏蔽原型属性)
如何验证当前属性来自哪一层?
可用以下方法区分属性来源:
-
obj.hasOwnProperty('prop')→ 是否为自有属性(不查原型) -
Object.prototype.propertyIsEnumerable.call(obj, 'prop')→ 自有且enumerable: true -
Object.getOwnPropertyDescriptor(obj, 'prop')→ 获取obj上该属性的完整描述符(返回undefined表示不在自身) -
Object.getPrototypeOf(obj)配合递归调用getOwnPropertyDescriptor,可定位属性在原型链中的具体位置
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











