作者:watermelo37 涉及领域:Vue、SpingBoot、Docker、LLM、python等 ------------------------------------------------------------------------------------------------------------------------- --------------------------温柔地对待温柔的人,包容的三观就是最大的温柔。-------------------------- -------------------------------------------------------------------------------------------------------------------------
JavaScript 的原型链(prototype chain)是理解 JavaScript 对象和继承机制的关键。它是通过对象的原型(prototype)属性实现的,用于实现对象属性和方法的共享和继承。以下是对 JavaScript 原型链的详细介绍,这一篇文章将会通过理论与demo相结合的方式,力争一文概括原型、对象、原型链以及基于原型链实现JavaScript的继承机制的所有方面,帮助您一站式搞定原型链。
在 JavaScript 中,每个对象都有一个与之关联的原型对象(prototype)。通过原型,对象可以继承属性和方法。
构造函数是用来创建对象的函数。通过 new 关键字调用构造函数,会创建一个新的对象,并将这个对象的 __proto__ 属性指向构造函数的 prototype 对象。
function Person(name) {
this.name = name;
}
const person1 = new Person('Alice');
console.log(person1.__proto__ === Person.prototype); // true
原型链是一系列通过 __proto__ 属性相互连接的对象,用于实现属性和方法的继承。如果访问一个对象的属性时,这个对象本身没有该属性,JavaScript 会沿着原型链向上查找,直到找到该属性或达到原型链的末端(即 null)。
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log(`Hello, my name is ${this.name}`);
};
const person1 = new Person('Alice');
person1.greet(); // Hello, my name is Alice
console.log(person1.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__ === null); // true
在上述代码中,当调用 person1.greet() 时,JavaScript 首先检查 person1 对象是否有 greet 方法。如果没有,则沿着原型链查找,最终在 Person.prototype 找到 greet 方法并调用。
原型链的终点是 Object.prototype,它的 __proto__ 属性为 null,表示原型链的终点。
通过构造函数创建对象时,新对象的 __proto__ 属性会指向构造函数的 prototype 对象。
function Animal(type) {
this.type = type;
}
const dog = new Animal('dog');
console.log(dog.__proto__ === Animal.prototype); // true
Animal.prototype 本身也是一个对象,它的 __proto__ 属性指向 Object.prototype,这是原型链的一部分。
console.log(Animal.prototype.__proto__ === Object.prototype); // true
通过设置原型对象实现继承。
function Animal(type) {
this.type = type;
}
Animal.prototype.speak = function() {
console.log(`This ${this.type} makes a sound`);
};
function Dog(name) {
Animal.call(this, 'dog');
this.name = name;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
console.log(`${this.name} barks`);
};
const dog = new Dog('Buddy');
dog.speak(); // This dog makes a sound
dog.bark(); // Buddy barks
在上述代码中,Dog 继承了 Animal。通过 Object.create(Animal.prototype) 设置 Dog.prototype 的原型为 Animal.prototype,从而实现继承。
ES6 引入了 class 语法,使得创建和继承类更加简洁。
class Animal {
constructor(type) {
this.type = type;
}
speak() {
console.log(`This ${this.type} makes a sound`);
}
}
class Dog extends Animal {
constructor(name) {
super('dog');
this.name = name;
}
bark() {
console.log(`${this.name} barks`);
}
}
const dog = new Dog('Buddy');
dog.speak(); // This dog makes a sound
dog.bark(); // Buddy barks
综上所述,可以得出: