什么是原型链
什么是原型链?
原型链是指由每个对象的原型组成的链式结构。在 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
的实现也会被更改,因为它们共
转载自:https://juejin.cn/post/7231822940559720508