likes
comments
collection
share

什么是原型链

作者站长头像
站长
· 阅读数 9

什么是原型链?

原型链是指由每个对象的原型组成的链式结构。在 JavaScript 中,每个对象都有一个原型对象(除了 Object.prototype)。如果一个对象需要访问另一个对象的属性或方法,但该属性或方法并不存在于该对象本身,则会沿着原型链向上查找,直到找到该属性或方法或者到达原型链的顶层。

例如,考虑以下代码:

var obj = { a: 1 };
console.log(obj.hasOwnProperty('a'));    // true
console.log(obj.hasOwnProperty('toString'));    // false
console.log(Object.prototype.hasOwnProperty('toString'));    // true

这里的 obj 对象有一个属性 a,因此调用 hasOwnProperty('a') 方法会返回 true。然而,它并没有自己的 toString 方法,因此调用 hasOwnProperty('toString') 方法会返回 false。但是,obj 的原型对象是 Object.prototype,而 Object.prototype 上有一个 toString 方法,因此最终结果为 true

如何使用原型链?

原型链的主要用途是创建共享属性和方法的对象。考虑以下示例:

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

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

var person1 = new Person('Alice');
var person2 = new Person('Bob');

person1.sayHello();    // "Hello, my name is Alice"
person2.sayHello();    // "Hello, my name is Bob"

在这个例子中,我们首先定义了一个 Person 构造函数,用于创建人物对象。然后我们将一个 sayHello 方法添加到 Person.prototype 中,而不是直接将其添加到 Person 对象本身。这样做的好处是,所有由 Person 构造函数创建出来的对象都可以共享 sayHello 方法,从而使代码更为简洁和易于维护。

原型链的缺点

原型链是一种非常强大的语言特性,但它也有一些缺点。其中最显著的缺点之一是可能会导致对象之间的混乱关系。

举个例子,考虑以下代码:

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

Animal.prototype.sayName = function() {
  console.log('My name is ' + this.name);
};

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

Dog.prototype = Object.create(Animal.prototype);

Dog.prototype.bark = function() {
  console.log('Woof!');
};

var dog1 = new Dog('Fido');
var dog2 = new Dog('Spot');

dog1.sayName();    // "My name is Fido"
dog2.sayName();    // "My name is Spot"

在这个例子中,我们首先定义了一个 Animal 构造函数,用于创建动物对象,并将一个 sayName 方法添加到它的原型对象中。然后我们定义了一个 Dog 构造函数,用于创建狗对象,并使用 Object.create() 函数来继承 Animal.prototype 上的属性和方法。最后我们将一个 bark 方法添加到 Dog.prototype 中。

这看起来似乎很好,但实际上存在问题。如果我们尝试更改 Dog.prototype.sayName 的实现,例如:

Dog.prototype.sayName = function() {
  console.log('Woof woof!');
};

那么 Animal.prototype.sayName 的实现也会被更改,因为它们共