JS的几种继承方式
我们来谈谈JS的继承吧
原型链继承
方式 son.prototype = new father()
1 | function grandFather() { |
方法缺陷: 多个子实例会改变引用类型
1 | function SuperType(){ |
检测是否属于原型上的实例
- instanceof :
运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。返回布尔。
最高级对象是 Object
1
2
3
4
5
6
7var myString = new String();
myString instanceof String; // 返回 true
myString instanceof Object; // 返回 true
[] instanceof Array // true
[] instanceof Object // true
{} instanceof Object // true
- hasOwnProperty :
检测自身原型上是否有传入参数的属性,返回布尔1
2
3
4
5const object1 = {};
object1.property1 = 42;
console.log(object1.hasOwnProperty('property1')); // true
console.log(object1.hasOwnProperty('toString')); // false
console.log(object1.hasOwnProperty('hasOwnProperty')) // false
构造函数 结合call
继承
描述:核心代码是SuperType.call(this)
,创建子类实例时调用SuperType构造函数,于是SubType的每个实例都会
将SuperType中的属性复制一份
。
1 | function SuperType(){ |
(1) 只能继承父类的实例属性和方法,不能继承原型属性/方法
(2) 无法实现复用,`每个子类都有父类实例函数的副本`,影响性能
Object.create
也就是提供一个返回一个新对象,并且该对象的__proto__指向传入的对象
语法
1 | Object.create(proto[, propertiesObject]) |
1 | // 原理 |
(1) 原型链继承多个实例的引用类型属性指向相同,存在篡改的可能。
(2) 无法传递参数
ES6 class extends
super
1 | class Rectangle { // class 名一般都是大写开头 |
class 的 继承 extends 关键字
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 继承
class Square extends Rectangle {
constructor(length) {
super(length, length);
this.name = 'Square'; // 如果子类中存在构造函数,则需要在使用“this”之前首先调用 super()。
}
get area() {
return this.height * this.width;
}
}
const square = new Square(10);
console.log(square.area);
// 输出 100class 实际上是函数的语法糖🍬
1
2typeof Rectangle // 'function'
typeof Square // 'function'
ES5继承和ES6继承的区别
- ES5的继承实质上是先创建子类的实例对象,然后再将父类的方法添加到this上(Parent.call(this)).
- ES6的继承有所不同,实质上是先创建父类的实例对象this,然后再用子类的构造函数修改this。
因为子类没有自己的this对象,所以必须先调用父类的super()方法,否则新建实例报错。
- 本文标题:JS的几种继承方式
- 本文作者:Jonnzer
- 创建时间:2020-04-07 17:20:35
- 本文链接:https://jonnzer.github.io/2020/04/07/JS/继承/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
评论