返回

无需困惑!三分钟带你读懂原型链指向

前端

原型链是指向一组对象的链接,这些对象共享一组共同的属性和方法。当一个对象需要访问一个它不直接拥有的属性或方法时,它会沿着原型链向上查找,直到找到该属性或方法。

原型链的指向问题

在 JavaScript 中,原型链的指向问题是指当一个对象的原型链指向另一个对象时,可能会导致意外的行为。例如:

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

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

const person1 = new Person('John');
const person2 = new Person('Jane');

// 修改 person1 的原型链,指向 person2
person1.__proto__ = person2;

// 当 person1 调用 greet() 方法时,会先在 person1 的原型链上查找 greet() 方法,
// 找不到后会沿着原型链向上查找,找到 person2 的 greet() 方法并执行
person1.greet(); // 输出:Hello, my name is Jane

在上面的示例中,当 person1 调用 greet() 方法时,由于 person1 的原型链指向 person2,因此会先在 person1 的原型链上查找 greet() 方法,找不到后会沿着原型链向上查找,找到 person2 的 greet() 方法并执行。因此,输出结果是 “Hello, my name is Jane”,而不是 “Hello, my name is John”。

如何避免原型链的指向问题

为了避免原型链的指向问题,可以使用 Object.create() 方法来创建一个新对象,该对象具有指定的原型。例如:

const person1 = Object.create(Person.prototype);
person1.name = 'John';

const person2 = Object.create(Person.prototype);
person2.name = 'Jane';

// 修改 person1 的原型链,指向 person2
person1.__proto__ = person2;

// 当 person1 调用 greet() 方法时,由于 person1 的原型链指向 person2,因此会先在 person1 的原型链上查找 greet() 方法,
// 找不到后会沿着原型链向上查找,找到 person2 的 greet() 方法并执行
person1.greet(); // 输出:Hello, my name is Jane

在上面的示例中,使用 Object.create() 方法创建了 person1 和 person2 对象,这两个对象都具有 Person.prototype 的原型。因此,当 person1 调用 greet() 方法时,会先在 person1 的原型链上查找 greet() 方法,找不到后会沿着原型链向上查找,找到 Person.prototype 的 greet() 方法并执行。因此,输出结果是 “Hello, my name is John”,而不是 “Hello, my name is Jane”。

总结

原型链的指向问题是指当一个对象的原型链指向另一个对象时,可能会导致意外的行为。为了避免原型链的指向问题,可以使用 Object.create() 方法来创建一个新对象,该对象具有指定的原型。