如何理解javascript原型_原型链的机制是什么【教程】

11次阅读

javaScript原型链是属性查找的默认行为,核心在于__proto__指向实例原型、prototype为函数提供原型起点、constructor指回构造函数new操作符自动设置obj.__proto__ === Foo.prototype,引擎据此向上查找属性。

如何理解javascript原型_原型链的机制是什么【教程】

javascript 的原型和原型链不是“机制设计”,而是对象查找属性时的默认行为——理解它,关键在搞清 __proto__prototypeconstructor 三者谁指向谁、何时被自动设置。

为什么 new Foo() 创建的对象能访问 Foo.prototype 上的方法?

因为 new 操作符会自动把新对象的 __proto__ 指向 Foo.prototype。这不是赋值,是引擎内置规则:

  • function Foo() {} 声明后,Foo.prototype 自动创建(是个普通对象,带 constructor 指回 Foo
  • const obj = new Foo() 执行时,obj.__proto__ === Foo.prototypetrue
  • 当读取 obj.methodobj 自身无该属性时,js 引擎顺着 obj.__proto__ 向上找,即查到 Foo.prototype.method

__proto__prototype 容易混淆的三个事实

它们名字像,但作用对象完全不同:

  • __proto__ 是每个实例对象(如 {}new date())都有的内部属性,指向它的“原型对象”
  • prototype 是每个函数对象(包括 class)才有的属性,仅用于 new 实例时提供原型链起点
  • Object.prototype.__proto__NULL——这是原型链终点,不是“没设置”,而是明确终止查找

Object.getPrototypeOf()Object.setPrototypeOf() 替代直接操作 __proto__

__proto__ 是非标准遗留属性,虽被广泛支持但不推荐直接读写:

立即学习Java免费学习笔记(深入)”;

  • 查原型应统一用 Object.getPrototypeOf(obj),它等价于 obj.__proto__ 但更规范
  • 改原型必须用 Object.setPrototypeOf(obj, proto);直接赋值 obj.__proto__ = x严格模式下会静默失败
  • 性能上,动态修改 __proto__ 会破坏 V8 等引擎的内联缓存(IC),导致后续属性访问变慢

class 语法下原型链怎么走?

es6 class 是语法糖,底层仍靠函数和原型链工作:

  • class A {} 编译后本质是 function A() {}A.prototype 依然存在
  • class B extends A {} 中,B.prototype.__proto__ === A.prototype,同时 B.__proto__ === A(静态方法继承
  • 注意:类体中定义的方法会自动添加到 B.prototype,但 Static 方法挂在 B 自身,不在原型链上

真正容易卡住的地方,往往不是“原型链怎么连”,而是忘记 __proto__ 是实例属性、prototype 是函数属性,或者在用 Object.create(null) 创建对象后还试图沿链找 toString ——那条链从一开始就被切断了。

text=ZqhQzanResources