关于原型和原型链

关于原型和原型链
最新回答
虚伪无情

2022-11-25 17:42:59

原型和原型链是JavaScript面向对象编程的核心概念,通过隐式原型(__proto__)和显式原型(prototype)的关联形成属性查找的链式结构,实现继承机制。 以下是详细解释:

一、四个核心规则
  1. 引用类型可自由扩展属性所有引用类型(如Object、Array、Function等)均可动态添加属性。例如:

    const obj = {};obj.a = 1; // 对象扩展属性const arr = [];arr.a = 1; // 数组扩展属性const fn = function() {};fn.a = 1; // 函数扩展属性
  2. 引用类型具有隐式原型__proto__每个引用类型实例均有一个__proto__属性,指向其构造函数的显式原型prototype。例如:

    const obj = {};console.log(obj.__proto__); // 输出Object.prototype

  3. 隐式原型指向构造函数的显式原型实例的__proto__与构造函数的prototype严格相等。例如:

    const arr = [];console.log(arr.__proto__ === Array.prototype); // trueconst fn = function() {};console.log(fn.__proto__ === Function.prototype); // true
  4. 属性查找遵循原型链当对象自身不存在某属性时,会沿__proto__向上查找,直到Object.prototype或null。例如:

    const obj = { a: 1 };console.log(obj.toString); // 输出? toString() { [native code] }// 查找路径:obj → Object.prototype.toString
二、原型链的构成与特例
  • 原型链的形成实例的__proto__指向构造函数prototype,而prototype本身也是对象,其__proto__继续指向更高层构造函数的prototype,最终终止于Object.prototype.__proto__ === null。例如:

    function Person(name) { this.name = name; }const nick = new Person("nick");console.log(nick.toString); // 输出? toString() { [native code] }// 查找路径:nick → Person.prototype → Object.prototype.toString

  • 终止条件原型链最顶层为Object.prototype,其__proto__指向null,避免无限循环。

三、instanceof运算符的原理

instanceof通过检查构造函数的prototype是否存在于对象的原型链中来判断类型。简易实现如下:

function instance_of(L, R) { const baseType = ['string', 'number', 'boolean', 'undefined', 'symbol']; if (baseType.includes(typeof L)) return false; let RP = R.prototype; L = L.__proto__; while (true) { if (L === null) return false; if (L === RP) return true; L = L.__proto__; }}// 示例function Foo(name) { this.name = name; }const f = new Foo('nick');console.log(instance_of(f, Foo)); // trueconsole.log(instance_of(f, Object)); // true

判断流程

  1. f instanceof Foo:直接比较f.__proto__ === Foo.prototype,结果为true。
  2. f instanceof Object:f.__proto__指向Foo.prototype,继续比较Foo.prototype.__proto__ === Object.prototype,结果为true。
四、总结
  • 原型:构造函数的prototype属性,用于存储共享属性和方法。
  • 原型链:通过__proto__将实例与构造函数、父构造函数连接成的链式结构,实现属性继承。
  • 关键点

    所有对象最终继承自Object.prototype。

    属性查找沿原型链逐级向上,直到null终止。

    instanceof通过原型链验证类型关系。

理解原型和原型链后,可更高效地设计JavaScript的继承和复用逻辑。