第3课_原型与原型链
热度🔥:68 免费课程
授课语音
理解原型和原型链的关系与运用
JavaScript 中的原型和原型链是对象继承和属性查找的核心概念。理解原型和原型链的工作原理是掌握 JavaScript 对象机制的关键。本课将深入解析原型、原型链的定义及其在实际开发中的运用。
1. 什么是原型(Prototype)
在 JavaScript 中,每个对象都有一个属性 prototype
,这个属性指向一个对象,我们称这个对象为“原型”。对象的原型对象包含了可以被该对象访问和继承的属性和方法。
1.1 原型的作用
- 继承:通过原型,JavaScript 实现了对象的继承机制,允许子对象继承父对象的属性和方法。
- 共享方法和属性:多个实例对象可以共享原型中的属性和方法,从而节省内存。
// 创建一个对象并设置原型
function Person(name, age) {
this.name = name;
this.age = age;
}
// 在 Person 的原型上添加一个方法
Person.prototype.sayHello = function() {
console.log(`你好,我是 ${this.name}`);
};
// 创建 Person 的实例
let person1 = new Person('张三', 25);
person1.sayHello(); // 输出:你好,我是 张三
详细解释:
Person.prototype.sayHello
定义了一个方法sayHello
,所有通过Person
构造函数创建的实例都可以访问这个方法。- 即使实例没有定义
sayHello
方法,也可以通过原型继承到这个方法。
2. 原型链(Prototype Chain)
原型链是指对象通过其 prototype
属性形成的链式结构。当访问对象的某个属性时,如果对象本身没有该属性,JavaScript 会继续沿着原型链向上查找,直到找到该属性或达到原型链的顶端 null
。
2.1 原型链的工作机制
每个对象都有一个内部属性 [[Prototype]]
,它指向该对象的原型。当访问一个属性时,JavaScript 首先检查对象本身是否有该属性。如果没有,就查找对象的原型,依此类推,直到找到属性或者原型链末端。
// 创建一个对象并设置原型
function Animal(name) {
this.name = name;
}
Animal.prototype.sayHello = function() {
console.log(`${this.name} 在叫`);
};
function Dog(name, breed) {
Animal.call(this, name); // 继承 Animal 构造函数的属性
this.breed = breed;
}
// 继承 Animal 的原型
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog; // 修复 constructor 引用
// 在 Dog 的原型上添加一个方法
Dog.prototype.bark = function() {
console.log(`${this.name} 在叫汪汪`);
};
// 创建 Dog 的实例
let dog = new Dog('小狗', '比熊');
dog.sayHello(); // 输出:小狗 在叫
dog.bark(); // 输出:小狗 在叫汪汪
详细解释:
Dog.prototype = Object.create(Animal.prototype)
将Dog
的原型设置为Animal
的原型,这样Dog
就能继承Animal
的方法。- 在创建
dog
实例时,首先会查找dog
是否有sayHello
方法,若没有,则会沿着原型链查找,最终在Animal.prototype
中找到该方法。
3. 原型链的继承关系
通过原型链,JavaScript 实现了继承的机制。在继承中,子类对象可以访问父类对象的方法和属性。原型链的继承关系可以通过构造函数的 prototype
属性来实现。
3.1 继承的两种方式
- 原型链继承:子类的原型指向父类的实例,继承父类的方法和属性。
- 构造函数继承:通过
call
或apply
方法将父类构造函数的属性和方法继承到子类实例中。
// 原型链继承的例子
function Animal(name) {
this.name = name;
}
Animal.prototype.sayHello = function() {
console.log(`${this.name} 在叫`);
};
function Dog(name, breed) {
Animal.call(this, name); // 使用构造函数继承
this.breed = breed;
}
// 使用原型链继承父类的方法
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
// 在 Dog 的原型上添加方法
Dog.prototype.bark = function() {
console.log(`${this.name} 在叫汪汪`);
};
let dog = new Dog('小狗', '哈士奇');
dog.sayHello(); // 输出:小狗 在叫
dog.bark(); // 输出:小狗 在叫汪汪
详细解释:
Dog.prototype = Object.create(Animal.prototype)
实现了Dog
对象继承了Animal
对象的原型。Animal.call(this, name)
使用构造函数的call
方法将Animal
构造函数中的属性赋值给Dog
实例。
4. 原型与对象的继承关系图解
在 JavaScript 中,所有对象的原型最终都会继承自 Object.prototype
,这是原型链的顶端。以下是对象的继承关系示意图:
对象实例 → 构造函数.prototype → Object.prototype → null
4.1 具体例子:
let obj = { name: '张三' };
console.log(obj.toString()); // 输出:[object Object]
详细解释:
obj
作为一个普通对象,它的原型链最终会查找到Object.prototype
,因此它能继承Object.prototype
中的toString
方法。Object.prototype
是所有对象的顶级原型。
5. 总结
- 原型:每个对象都有一个原型对象,原型对象包含了该对象可以继承的属性和方法。
- 原型链:原型链是对象之间通过原型关联形成的链式结构。通过原型链查找属性和方法。
- 原型继承:JavaScript 中的继承机制通过原型链实现,子类可以继承父类的方法和属性。
- 构造函数与原型链结合:通过构造函数和原型链结合,可以实现 JavaScript 的继承机制,避免重复代码,提高代码复用性。
掌握原型和原型链的机制,是理解 JavaScript 面向对象编程的关键。