es5和es6类继承的主要区别

在es5中当我们谈到类,就会想到构造函数,原型等,其实在es6中也有这些东西,ES6中的类只是语法糖,它并没有改变类实现的本质。下面我们来分别看看es5和es6的类的继承!

1. es5的继承
function FatherClass(name){
this.family=['father','mother','daughter'];
this.name = name
};
FatherClass.prototype.getName =function(){
console.log(this.name);
};
function ChilderClass(name,age){
//子类继承父类(没涉及到父类原型)
FatherClass.call(this,name)
this.age =age;
};
function F(){};
//过渡函数的原型继承父对象
F.prototype =FatherClass.prototype;
ChilderClass.prototype = new F();
var instance = new ChilderClass('lily',18);

这个就是es5的类继承,它分两种继承方式:构造函数继承和原型继承!子类继承父类的时候,先创造子类的实例对象this,然后再将父类的方法或者属性添加到this上面(FatherClass.call(this,name)),然后再去继承原型链!如果我们要用es5写法去实现原生构造函数的继承(原生构造函数是指语言内置的构造函数)会是怎么写呢?

function MyArray() {
  Array.apply(this, arguments);
};
MyArray.prototype = Object.create(Array.prototype);
MyArray.prototype.constructor = MyArray;
var colors = new MyArray();
colors[0] = "red";
colors.length  // 0
colors.length = 0;
colors[0]  // "red"

上面代码定义了一个继承 Array 的MyArray类。但是,这个类的行为与Array完全不一致。之所以会发生这种情况,是因为子类无法获得原生构造函数的内部属性,ES5 是先新建子类的实例对象this,再将父类的属性添加到子类上,由于父类的内部属性无法获取,导致无法继承原生的构造函数!

2. es6的继承

还是基于上面的例子用es6的写法

class FatherClass {
    family = ['father', 'mother', 'daughter'];
    constructor(name) {
        this.name = name
    }
    getName() {
        console.log(this.name);
    }
};

class ChilderClass extends FatherClass {
    constructor(name, age) {
        super(name);
        this.age = age;
    }
};
var instance = new ChilderClass('lily', 18);

看起来是不是舒服多了?这里类继承机制完全和es5不一样,先调用super方法将父类实例对象的属性和方法加到this上面,然后再用子类的构造函数修改this。在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例!

console.log(ChilderClass.__proto__ === FatherClass);//true
console.log(ChilderClass.prototype.__proto__ === FatherClass.prototype);//true

这里比es6多了个静态方法继承,因为ChilderClass要继承FatherClass,那么FatherClass的静态属性和方法也都需要继承,所以 ChilderClass=Object.create(FatherClass)或者 Object.setPrototypeOf(ChilderClass,FatherClass).用es5一样ChilderClass.prototype也必须是FatherClass.prototype的实例!然后我们看下实现原生构造函数的继承(原生构造函数是指语言内置的构造函数)

class MyArray extends Array {
constructor(...args) {
  super(...args);
}
};
var colors= new MyArray();
colors[0] = "red";
colors.length  // 1
colors.length = 0;
colors[0]  // underfined

所以总体看来,es5类继承和es6类继承区别还是有些区别的!以上为我个人观点,如果有不正确的,请指正,不胜感激!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章