javascript中属性继承与隐藏由原型链查找和赋值规则实现:读取时沿__proto__向上搜索,赋值同名属性则在实例上创建以屏蔽原型属性,delete可恢复原型访问,无原生private修饰符。

JavaScript 中属性的继承与隐藏本质上是通过原型链的查找机制和属性赋值规则实现的,不是靠“声明”或“修饰符”,而是靠运行时的属性访问逻辑。
属性继承:沿着原型链向上查找
当读取对象属性时,JavaScript 引擎会先在对象自身查找;若未找到,则沿 __proto__(即 Object.getPrototypeOf())逐级向上搜索,直到原型为 null。这个过程就是继承的体现。
- 构造函数的
prototype对象会被新实例的__proto__指向,因此所有实例共享其上的属性和方法 - 方法通常定义在原型上,避免重复创建;数据属性一般定义在实例上,防止共享引用带来的副作用
- 例如:
Array.prototype.map可被所有数组调用,但每个数组的length是自身属性,不从原型继承
属性隐藏:在实例上赋值会屏蔽原型属性
当给实例赋值一个已有同名属性时(如 obj.prop = value),引擎会在该实例上创建(或更新)自有属性,从而“遮蔽”原型链上同名属性——后续读取将不再访问原型,这叫属性隐藏(shadowing)。
- 隐藏只影响读取和写入,不影响原型本身;删除实例属性后,原型属性重新可见
-
delete obj.prop可移除实例属性,恢复对原型属性的访问 - 使用
hasOwnProperty()可判断属性是否在实例自身上,而非原型链中
显式控制继承与隐藏的常用方式
开发者可通过多种方式主动管理属性的归属与可见性:
- 用
Object.defineProperty()设置enumerable: false或writable: false,限制遍历或修改行为 - 用
Object.create(proto, descriptors)精确指定新对象的原型及自有属性 - ES6 类中,
constructor内赋值(this.x = ...)创建实例属性;类体中定义的方法自动添加到原型上 - 避免在原型上直接放可变对象(如数组、对象),否则多个实例会意外共享,导致“伪隐藏失效”
注意:没有真正的“私有”或“protected”修饰
JavaScript 原生不提供访问控制关键字(如 private)。所谓“隐藏”只是约定或机制层面的屏蔽,并非语法级封装:
- 下划线前缀(如
_internal)是社区约定,不代表技术限制 - 闭包 + WeakMap 或 ES2022 的 # 私有字段(
#field)才能实现真正不可枚举、不可外部访问的私有状态 - 原型链上的属性始终可通过
Object.getPrototypeOf(obj).prop显式访问,无法完全隐藏
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











