es6 继承

1. 关于class的本质

定义一个类

class Person{
    constructor(skin,language){
        this.skin=skin;
        this.language=language;
    }
    say(){
        console.log('I am a Person')
    }
}

由于class本质还是一个function,因此它就会拥有一个的prototype属性,当new一个class时,会把class的porototype属性赋值给这个新对象的 __proto__属性。(prototype是函数的一个属性,它是一个指针。对于构造函数来说,prototype是作为构造函数的属性。prototype也可以是一个对象,prototype是对象实例的原型对象。所以prototype即是属性,又是对象。好绕啊~~~~
在new一个对象时,可以理解为一个对象没有ptototype属性,所以把ptototype给一个对象的 __proto__。

console.log(typeof Person);//function
var p = new Person('unkown','unknown');
console.log(p);//Person {skin: "unkown", language: "unknown"}
console.log( __proto__==Person.prototype);//ture

new一个对象时,会经历以下几个步骤(摘自javascript高级程序设计):
(1)创建一个对象;
(2)将构造函数的作用域赋值给新对象(因此this就指向了这个新对象);
(3)执行构造函数中的代码(为这个新对象添加属性);
(4)返回新对象
由此可见console.log(p)的结果。

2.constructor方法

constructor 方法是默认的方法,在new一个对象时,自动调用该方法。在一个类中必须有一个constructor,如果没有定义,则会默认添加一个。

constructor() {}

3.class的继承

和其他面向对象语言一样,class用extends实现继承。
1)子类没constructor时

class American extends Person{
    aboutMe(){
        console.log(this.skin+' '+this.language)
    }
}

子类American继承父类Person,子类没用定义constrcutor,则默认添加一个,并且在constrcutor中调用super函数,相当于调用父类的构造函数。调用super函数是为了在子类中获得父类的this,调用之后this指向子类。也就是父类.prototype.constructor.call(this)。

class Chinese extends Person{
    constructor(skin,language,positon){
        //console.log(this);//报错
        super(skin,language);
        //super();
        //console.log(this);调用super后得到了this,不报错
        this.positon=positon;
    }
    aboutMe(){
        console.log(this.skin+' '+this.language+' '+this.positon);
    }
}

2)子类有constructor
子类必须在constructor方法中调用super方法,否则new实例时会报错。因为子类没有自己的this对象,而是继承父类的this对象。如果不调用super函数,子类就得不到this对象。super()作为父类的构造函数,只能出现在子类的constructor()中;但是super指向父类的原型对象,可以调用父类的属性和方法。

class Chinese extends Person{
    constructor(skin,language,positon){
        //console.log(this);//在没有调用super之前输出this会报错
        super(skin,language);
        //super();//不给父类构造函数传参,父类的构造数的值为undefined
        console.log(this);
        this.positon=positon;
    }
    aboutMe(){
        console.log(this.x+' '+this.y+' '+this.positon);
    }
}

4.实例化子类对象

实例化子类对象时,子类对象可以拥有父类的属性和方法,子类对象还可以拥有自己的属性和方法。比如chinese 继承了父类的say方法,还拥有自己的chinese say方法。最后两行代码表示
1)子类的__proto__属性,表示构造函数的继承,总是指向父类。

2)子类的prototype属性的__proto__属性表示方法的继承,总是指向父类的prototype属性-----摘自阮一峰老师的ES6入门

var american = new American('white','English');
var chinese =new Chinese('yellow','chinese','changsha');
chinese.say();//I am a Person
chinese.chinesesay();//I am a Person   I am a Chinese
console.log(American.__proto__===Person);//true 
console.log(American.__proto__);//父类对象
console.log(American.prototype.__proto__===Person.prototype);//true

ES6 class的继承使用细节

2017年04月28日 17:43:00

阅读数:3881

扫描二维码关注公众号,回复: 2384744 查看本文章

ES6 class的继承与java的继承大同小异,如果学过java的话应该很容易理解,都是通过extends关键字继承。

 
  1. class Animal{

  2. constructor(color){

  3. this.color = color;

  4. };

  5. }

  6. class Bear extends Animal{

  7. constructor(){

  8. super();

  9. }

  10. }

其余的就不多说了,这里着重讲一下ES6中super关键字的使用。

ES6子类继承父类,必须在constructor函数的第一行调用super();之后才能使用关键字this,这是因为子类中没有自己的this对象,而是继承父类的this对象,然后才能为这个this添加相应的属性和方法。不然就会报错,相当于Parent.apply(this);而SE5则正好和这个相反,它先创造了自己的this对象,然后才添加父类的方法属性到这个对象里。

super在子类中一般有三种作用

  1. 作为父类的构造函数调用,就是上面所说的那种方法。
  2. 在普通方法中,作为父类的实例调用
  3. 在静态方法中,作为父类调用

在普通方法中调用,此时指向父类的实例

 
  1. class Animal{

  2. constructor(color){

  3. this.color = color;

  4. }

  5. run(){

  6. return "run";

  7. }

  8. }

  9. class Bear extends Animal{

  10. constructor(){

  11. super();

  12. console.log(super.run());

  13. }

  14. }

在静态方法中调用,此时指向父类

 
  1. class Animal{

  2. constructor(color){

  3. this.color = color;

  4. }

  5. run(){

  6. return "run";

  7. }

  8. static run(){

  9. return "static run"

  10. }

  11. }

  12. class Bear extends Animal{

  13. constructor(){

  14. super();

  15. console.log(super.run());//run

  16. }

  17. static go(){

  18. super.run();//static run

  19. }

  20. }


 

猜你喜欢

转载自blog.csdn.net/qq_26632807/article/details/81215900