欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前端面试笔记-- js重要概念: 继承

程序员文章站 2022-03-04 12:22:45
...

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的继承方法,一定要注意区分对比不同的继承方式的优缺点。

原型链继承优点、特点:

  1. 简单,易于实现
  2. 父类新增原型方法和原型属性子类都可以访问到
  3. 子类构造的实例也是父类构造的实例(参见测试代码 cat instanceof Animal

原型链继承缺点:

  1. 子类可以重写父类原型上的方法: Cat.prototype._proto_.eat = null 。此时,父类上的原型方法eat已经被重置为null.
  2. 所有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

优点:

  1. 可以实现多继承(call多个父类对象)
  2. 创建子类实例时,可以向父类传递参数
  3. 解决了原型链继承中,子类实例共享父类引用属性的问题

缺点:

  1. 只能继承父类构造函数的方法和属性,不能继承父类显式原型上的属性和方法
  2. 每次实例化子类,都要调用一次父类的构造函数,对于父类构造函数中的方法,继承时,每次都要创建一次,无法实现函数的复用。

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

优点:

结合了原型链继承和构造函数继承的各自优势:

  1. 通过原型链继承父类的原型方法;
  2. 借助构造函数,继承父类属性。
    这也是比较常用的js继承方法,可以满足大多数的需求,一定要牢记哦~

缺点:

无论什么情况下,都会调用两次父级构造函数:一次是在创建子级原型的时候,另一次是在子级构造函数内部

(未完待续~)

相关标签: 面试 javascript