前端面试笔记-- js重要概念: 继承
程序员文章站
2022-03-04 12:22:45
...
前端面试笔记-- js重要概念: 继承
js继承
JS的继承也是其非常强大的特性之一,在面试中也是常被问及的知识点。s的继承可大致分为6种,笔者想通过一个具体的例子记述js的继承方式。
说到继承,那必然要有父类和字类,我们先写一个父类的构造函数,代码如下:
// 定义一个动物类
function Animal (name) {
// 属性
this.name = name || 'Animal';
// 实例方法
this.sleep = function(){
console.log(this.name + '正在睡觉!');
}
}
// 原型方法
Animal.prototype.eat = function(food) {
console.log(this.name + '正在吃:' + food);
};
这里的父类构造函数是Animal, 定义了动物的name属性、一个实例方法sleep, 同时,构造函数的显式原型prototype上定义了一个原型方法eat。通过
js的继承方式,要实现的是字类继承父类的属性和方法,比如:子类为Cat, 通过继承,子类Cat构造的实例对象myCat除了有子类构造函数Cat的属性和方法,也要包含父类的属性和方法。
1、原型链继承
原型链继承的核心只有一句话: 将父类的实例作为子类的原型
在本文的例子中即为:
function Cat(){
}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
// 测试
var cat = new Cat();
console.log(cat.name); // 'cat' 来自Cat.prototype.name
console.log(cat.eat('fish')); // cat正在吃: fish
console.log(cat.sleep()); // cat正在睡觉!
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
学习js的继承方法,一定要注意区分对比不同的继承方式的优缺点。
原型链继承优点、特点:
- 简单,易于实现
- 父类新增原型方法和原型属性子类都可以访问到
- 子类构造的实例也是父类构造的实例(参见测试代码
cat instanceof Animal
)
原型链继承缺点:
- 子类可以重写父类原型上的方法:
Cat.prototype._proto_.eat = null
。此时,父类上的原型方法eat已经被重置为null
. - 所有Cat实例化对象都一样,都共享有原型对象的属性及方法。修改一个,其他的实例对象也改变。
2、借助构造函数继承
话不多说,上代码:
function Cat(name, age){
Animal.call(this, name);
this.age = age;
}
// 测试
var cat = new Cat('Tom', 1);
console.log(cat.name); // Tom
console.log(cat.sleep()); // Tom正在睡觉!
console.log(cat.eat('fish')); // Uncaught TypeError: cat.eat is not a function
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
优点:
- 可以实现多继承(call多个父类对象)
- 创建子类实例时,可以向父类传递参数
- 解决了原型链继承中,子类实例共享父类引用属性的问题
缺点:
- 只能继承父类构造函数的方法和属性,不能继承父类显式原型上的属性和方法
- 每次实例化子类,都要调用一次父类的构造函数,对于父类构造函数中的方法,继承时,每次都要创建一次,无法实现函数的复用。
3、组合继承
也就是结合原型链继承和构造函数继承的优点。话不多说,还是上代码:
function Cat(name, age){
Animal.call(this, name);
this.age = age;
}
Cat.prototype = new Animal();
// 测试
var cat = new Cat('Tom', 1);
console.log(cat.name); // Tom
console.log(cat.sleep()); // Tom正在睡觉!
console.log(cat.eat('fish')); // Tom正在吃:fish
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
优点:
结合了原型链继承和构造函数继承的各自优势:
- 通过原型链继承父类的原型方法;
- 借助构造函数,继承父类属性。
这也是比较常用的js继承方法,可以满足大多数的需求,一定要牢记哦~
缺点:
无论什么情况下,都会调用两次父级构造函数:一次是在创建子级原型的时候,另一次是在子级构造函数内部
(未完待续~)
上一篇: Optional类