javaScript 中原型和原型链

98 阅读3分钟

JavaScript 原型机制

在 JavaScript 中,原型是实现对象继承和方法共享的核心机制。通过原型对象,不同的对象可以共享相同的属性和方法,而无需为每个对象重复定义这些内容。原型机制是 JavaScript 面向对象特性的重要实现方式。

1. prototype 属性

每个构造函数都有一个 prototype 属性,它指向该构造函数的原型对象。在这个原型对象上,可以定义共享的方法和属性,供所有通过该构造函数创建的实例对象使用。

示例:给数组封装一个求和方法

javascript
复制代码
Array.prototype.sum = function () {
  return this.reduce((prev, item) => prev + item, 0);
};

console.log([1, 2, 3].sum()); // 输出: 6

在上面的示例中,sum() 方法被添加到了 Array.prototype 上,这意味着所有数组实例都可以通过原型链共享这个方法,而无需为每个数组对象单独定义。

JavaScript 原型链

原型链是 JavaScript 实现对象属性查找机制的基础,通过它,JavaScript 可以在对象本身以及其原型上寻找属性和方法。在 JS 对象中会通过 proto 属性指向内部的原型对象,这些原型对象内部又有自己的原型,从而形成一个链式结构,称为原型链。

2. 原型链中的核心属性

  • __proto__ 属性:每个对象都有一个隐藏属性 __proto__,它指向该对象的原型,即构造函数的 prototype。这是实现原型链的关键,允许对象通过它查找继承自原型对象的属性和方法。
  • prototype 属性:构造函数的 prototype 属性指向一个原型对象,该原型对象上的属性和方法可以被所有实例对象共享。
  • constructor 属性prototype 对象上有一个 constructor 属性,指向构造函数本身。它用于标识哪个构造函数创建了该原型对象。

3. 原型链的作用

原型链的作用是,当访问一个对象的属性或方法时,JavaScript 引擎会首先在对象自身查找。如果找不到该属性或方法,JS 引擎会通过对象的 __proto__ 属性查找原型对象中的内容。如果原型对象中也找不到,就会沿着 __proto__ 一直向上查找,直到 Object.prototype,如果仍然找不到,则返回 null

原型链图示:

javascript
复制代码
obj.__proto__Star.prototypeObject.prototypenull

在查找时,如果找到了目标属性或方法,就会返回对应的值;如果没有找到,最后会返回 null,表明查找失败。


4. 示例:构造函数与原型链

javascript
复制代码
function Star(name) {
  this.name = name;
}

let obj = new Star('张三');

console.log(obj.__proto__ === Star.prototype); // true
console.log(Star.prototype.__proto__ === Object.prototype); // true
console.log(Star.prototype.constructor === Star); // true

在这个例子中:

  1. obj.__proto__ === Star.prototype:说明对象 obj 的原型指向 Star 构造函数的 prototype 属性,这意味着 obj 可以通过原型链访问 Star.prototype 上定义的属性和方法。
  2. Star.prototype.__proto__ === Object.prototypeStar.prototype 的原型指向 Object.prototype,这意味着通过原型链,Star 构造函数的所有实例(如 obj)都能继承 Object 的原型方法,例如 toString()
  3. Star.prototype.constructor === Star:表明 Star.prototypeconstructor 属性指向 Star 构造函数,确保原型对象是由 Star 构造函数创建的。

原型链分析图

image.png

总结

通过原型、__proto__prototypeconstructor 等概念,JavaScript 实现了强大的继承机制。原型链使得对象之间可以共享属性和方法,实现了代码的复用和扩展性。这种机制大大提高了 JavaScript 编程的灵活性和效率,使得我们可以通过面向对象的方式构建功能强大的应用程序。