Web 前端开发 让前端飞程序员

ES5/ES6原型链与继承

2017-12-11  本文已影响160人  4dfab65f4d18

ES5最经典的寄生组合式继承

原型链相关.png

注意

如果A.prototype没有constructor,只要B.prototype的原型对象是A.prototype,则b instance of A就为true

ES6和ES5继承的代码实现

//ES5继承
function Super(name){
    this.name=name
    this.colors=[1,2,3]
}
Super.prototype.sayName=function(){
    alert(this.name)
}
function Sub(name,age){
    Super.call(this,name)//显式传入this作为显示调用者调用父类构造函数
    this.age=age
}
Sub.prototype=Object.create(Super.prototype,{
    constructor:{
        value:Sub
    }
})//避免调用父类的构造函数
Sub.prototype.sayAge=function(){
    alert(this.age)
}

//ES6继承
class Super{
    constructor(name){
        this.name=name
    }
    sayName(){
        alert(this.name)
    }
    static haha(){
        alert(this.hahatext)//Super函数对象的静态属性
    }
}
Super.hahatext="dingxu1"
class Sub extends Super{
    constructor(name,age){
        super(name)//先实例化父构造函数,在更改this的指向,super()之后才有了this!
        this.age=age
    }
    sayAge(){
        alert(this.age)
    }
}
Sub.hahatext="dingxu2"
Super.haha()//dingxu1
Sub.haha()//dingxu2
/***********************************************/
Sub.__proto__ === Super // true 作为一个对象,子类(Sub)的原型(__proto__属性)是父类(Super)
Sub.prototype.__proto__ === B.prototype // true 作为一个构造函数,子类(Sub)的原型对象(prototype属性)是父类的原型对象(prototype属性)的实例。

class MyArray extends Array{
    constructor(...args){
        super(...args)
    }
}
var arr=new MyArray()
arr[0]=12
arr.length
arr.length=0
arr[0]

extends关键字不仅可以用来继承类,还可以用来继承原生的构造函数。因此可以在原生数据结构的基础上,定义自己的数据结构。

class VersionedArray extends Array {
  constructor() {
    super();
    this.history = [[]];
  }
  commit() {
    this.history.push(this.slice());
  }
  revert() {
    this.splice(0, this.length, ...this.history[this.history.length - 1]);
  }
}

var x = new VersionedArray();

x.push(1);
x.push(2);
x // [1, 2]
x.history // [[]]

x.commit();
x.history // [[], [1, 2]]

x.push(3);
x // [1, 2, 3]
x.history // [[], [1, 2]]

x.revert();
x // [1, 2]

注意,继承Object的子类,有一个行为差异。

class NewObj extends Object{
  constructor(){
    super(...arguments);
  }
}
var o = new NewObj({attr: true});
o.attr === true  // false

上面代码中,NewObj继承了Object,但是无法通过super方法向父类Object传参。这是因为 ES6 改变了Object构造函数的行为,一旦发现Object方法不是通过new Object()这种形式调用,ES6 规定Object构造函数会忽略参数。

上一篇下一篇

猜你喜欢

热点阅读