面试高频题:js原型和原型链

107 阅读2分钟

在 JavaScript 中,原型(Prototype)和原型链(Prototype Chain)是实现继承和对象属性查找的重要机制。它们允许对象共享方法和属性,从而提高代码的复用性。

1. 原型(Prototype)

每一个 JavaScript 对象都有一个属性叫做 __proto__,它指向该对象的原型(即构造函数的 prototype 属性)。原型对象也是一个对象,通常包含了构造函数的共享方法和属性。

  • 对象的原型由构造函数的 prototype 属性决定。
  • 对象实例可以通过其原型访问原型上定义的属性和方法。

例如:

function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log(`Hello, my name is ${this.name}`);
};

const person1 = new Person('Alice');
person1.sayHello(); // 输出 "Hello, my name is Alice"

在上面的例子中,Person 的实例 person1 通过其原型 Person.prototype 继承了 sayHello 方法。

2. 原型链(Prototype Chain)

原型链是 JavaScript 中用来查找对象属性和方法的机制。当访问一个对象的属性时,首先会检查对象本身是否有该属性。如果没有,JavaScript 会在该对象的原型上查找。如果原型上也没有,查找会继续沿着原型链向上进行,直到达到 null 为止。每个对象的原型又有自己的原型,这样形成一个链条,直到 Object.prototype 为止。

原型链的查找过程如下:

  1. 如果对象本身有该属性或方法,直接返回。
  2. 如果对象本身没有,查找对象的 __proto__,即对象的原型。
  3. 如果原型上也没有,继续查找原型的 __proto__,直到 Object.prototype
  4. 如果 Object.prototype 上也没有该属性或方法,最终返回 undefined

例如:

const obj = {
  name: 'John'
};

const person = Object.create(obj);
person.age = 30;

console.log(person.name); // 输出 "John" 来自 obj
console.log(person.age);  // 输出 30 来自 person

在这个例子中,person 对象通过 Object.create(obj) 创建,它继承了 obj 的原型。因此当我们访问 person.name 时,JavaScript 会先检查 person 本身没有 name 属性,然后查找 obj,发现 name 存在,最后返回 "John"。

总结

  • 原型(Prototype) 是每个对象都拥有的属性,指向该对象的构造函数的 prototype 对象,通常存放共享的方法和属性。
  • 原型链(Prototype Chain) 是属性查找的链式结构,JavaScript 通过该链来查找对象的属性和方法,直到找到为止,或者到达链的尽头 Object.prototype

原型和原型链是 JavaScript 继承机制的基础,它允许对象共享功能和实现继承。