返回
es5 实现继承:终结你的知识盲区,展现你对 JavaScript 的掌控力
前端
2023-10-01 01:29:27
通过原型链和构造函数巧妙实现 JavaScript 继承
原型链:对象关系的基石
在 JavaScript 中,每个对象都存在着一条原型链。原型链就像一个家庭关系网,每个对象都是这个网中的一员。它指向该对象的原型对象,而原型对象又指向自己的原型对象,以此类推,直到到达顶端的 null。
当对象试图访问不存在的属性或方法时,它会顺着原型链向上查找。如果找到它所寻找的,则会停止搜索。否则,它会继续沿着链条向上爬,直到找到该属性或方法,或到达原型链的终点。
构造函数:创造新对象的工厂
构造函数是 JavaScript 中一种独特的函数,专门用于创建新对象。当调用构造函数时,它会生成一个新对象,并将该对象的原型对象设置为构造函数的 prototype
属性。这个新对象就可以继承构造函数原型对象上的属性和方法了。
利用原型链和构造函数实现继承
现在,我们有了原型链和构造函数的基础知识,可以运用它们来实现继承。以下是步骤:
- 定义一个父类构造函数: 就像蓝图一样,定义父类构造函数,它将包含父类的属性和方法。
- 为父类构造函数定义属性和方法: 在父类构造函数中添加你希望父类具有的属性和方法。
- 定义一个子类构造函数: 子类构造函数就像从父类蓝图中复制出来的一个新蓝图,它将继承父类的属性和方法。
- 将子类构造函数的 prototype 属性设置为父类构造函数的实例: 这就像建立父子关系,让子类继承父类的原型对象。
- 在子类构造函数中定义自己的属性和方法: 除了继承父类的特性外,子类还可以定义自己的独特属性和方法,以扩展父类的功能。
实例演示
以下是一个简单示例,展示如何使用原型链和构造函数实现继承:
// 父类构造函数
function Person(name) {
this.name = name;
}
// 定义父类方法
Person.prototype.sayHello = function() {
console.log("Hello, my name is " + this.name);
};
// 子类构造函数
function Student(name, major) {
// 调用父类构造函数,让子类继承父类的属性和方法
Person.call(this, name);
// 定义子类自己的属性
this.major = major;
}
// 让子类继承父类原型对象
Student.prototype = Object.create(Person.prototype);
// 确保子类构造函数指向自身
Student.prototype.constructor = Student;
// 定义子类自己的方法
Student.prototype.study = function() {
console.log("I am studying " + this.major);
};
// 创建子类对象
var student = new Student("John", "Computer Science");
// 调用父类方法
student.sayHello(); // 输出:Hello, my name is John
// 调用子类方法
student.study(); // 输出:I am studying Computer Science
在这个示例中,Person
构造函数是父类,而 Student
构造函数是子类。Student
构造函数通过调用 Person.call(this, name)
来继承 Person
构造函数中的属性和方法。它还定义了自己的属性 major
和方法 study()
。
总结
继承是 JavaScript 中的一项重要功能,它使我们能够创建可重用和易于维护的代码。通过掌握原型链和构造函数的原理,我们可以轻松实现继承,从而让我们的代码更加强大和灵活。
常见问题解答
- 什么是原型链?
- 原型链是 JavaScript 中的对象关系网,它允许对象继承其他对象的属性和方法。
- 什么是构造函数?
- 构造函数是专门用于创建新对象的 JavaScript 函数。
- 如何使用原型链和构造函数实现继承?
- 定义父类和子类构造函数,将子类构造函数的原型属性设置为父类构造函数的实例,并在子类构造函数中定义自己的属性和方法。
- 原型链和构造函数有什么区别?
- 原型链是一种对象之间的关系,而构造函数是一种创建新对象的函数。
- 什么时候应该使用继承?
- 当需要创建具有相似属性和行为的不同对象类型时,可以使用继承。