原型与继承
JavaScript 的「继承」主要通过 原型链 实现:对象上查找不到的属性,会沿 [[Prototype]](可由 __proto__ 或 Object.getPrototypeOf 观察)继续查找。
每个对象与原型链
- 普通对象的默认原型是
Object.prototype,其再往上是null(链终点)。 - 数据类型 中除
null/undefined外,都可参与对象语义;原始类型访问属性时会有临时装箱。
prototype 与 constructor
- 函数(非箭头)在创建时会带有
prototype对象,默认含可追溯的constructor指回函数。 new Fn()创建的新对象,其[[Prototype]]指向Fn.prototype。
function Person(name) {
this.name = name
}
Person.prototype.say = function () {
return this.name
}检测与设置原型
Object.getPrototypeOf(obj)/Object.setPrototypeOf(后者频繁修改有性能代价)。Object.create(proto):以指定对象为原型创建新对象。instanceof:检查prototype是否出现在构造函数侧的 prototype 链上,语义与原型链对应,但对跨 realm、手工改原型等情况需小心。
属性查找与遮蔽
实例与原型上可存在同名属性:实例属性遮蔽原型上的同名属性。删除实例属性 delete obj.x 后,可能再次沿原型链可见 x。
class 语法(ES2015+)
class 是构造函数 + 原型的语法糖:
- 实例方法在
prototype上。 static在构造函数自身上。extends设置原型链,super调用父类构造或方法。
私有字段 #field(较新)提供真·词法私有,不通过原型枚举暴露。
更多语法糖归类见 ES6+。
与 this 的关系
原型上的方法中 this 通常为调用时的接收者(谁点出来调用就是谁),而不是定义时「所属类」。这与 函数 中 this 规则一致。