Class

ES6新增了class关键字,对面向对象编程有了更好的支持。

1,基本语法

class Point {
    constructor(x,y){
        this.x = x;
        this.y = y;
    }

    toString(){
        return `x is ${this.x}, y is ${this.y}`;
    }
}

const p = new Point(1,2);
const s = p1.toString();
console.log(s);//输出结果为x is 1, y is 2;

上面代码演示了ES6中的class的基本用法。

  • 使用class定义一个类
  • constructor为类的构造方法,当使用类实例化一个对象是,该方法会调用,并接受实例化时传入的参数
  • 类的属性不需要提前声明,可以直接使用,为定义的属性值为null
  • 声明类的方法时,不需要写function

2,this对象

this对象表示该类创建的对象,可以简单理解为自身。

this有两种使用场景:

  • 访问自身属性
  • 调用自身方法

    class Point {

      constructor\(x,y\){  
          this.x = x;  
          this.y = y;  
      }
    
      toString(){
          //通过this访问自身属性
          return `x is ${this.x}, y is ${this.y}`;
      }
    

    }

    class Point {

      constructor\(x,y\){  
          this.x = x;  
          this.y = y;  
      }
    
      toString(){
          //通过this访问自身属性
          return `x is ${this.x}, y is ${this.y}`;
      }
    
      logSelf(){
          //通过this调用自身方法
          const s = this.toString();
          console.log(s)
      }
    

    }

    const p1 = new Point(1,2);
    p1.logSelf();

3,手动绑定this对象

在特定情况下,类中的方法在调用时,会产生this为undefined的情况。这些情况较为复杂,后续章节会详细说明,在此不展开讲解。

例如,如下代码,变无法正常运行:

class Timer {
    constructor(x){
        this.x = x;
    }

    start(){
        setInterval(this.event,1000);
    }

    event(){
        console.log('a');
        console.log(this.x);
    }
}

const t = new Timer(1);
t.start();

上述代码的运行结果为,每秒钟,打印一个a字符,本应该一起打印的属性x的值,无法输出。

原因为,在此种情况下,event方法中的this对象为undefined,所以无法通过this对象访问属性x的值。

我们在学习初期,无法区分哪些情况this对象会丢失,所以我们采用一个统一的保守方案来修改此bug。

只要是自己写的方法且方法中用到了this对象,我们都统一在constructor方法中,手动对其绑定this对象,避免this对象丢失的情况发生。

class Timer {
    constructor(x){
        this.x = x;
        //手动绑定this
        this.event = this.event.bind(this);
    }
    start(){
        setInterval(this.event,1000);
    }
    event(){
        console.log('x');    
        console.log(this.x);
    }
}

const t = new Timer(1);
t.start();

通过手动绑定this对象之后,this对象丢失的情况便不会发生。

4,类的继承

在ES6中,提供的extends关键字用来实现类的继承关系。

class Base {
    say(){
        console.log('this is Base');
    }
}

class Sub extends Base {
    sayHello(){
        console.log('this is Sub');
    }
}

const s = new Sub();
s.say();//输出结果为this is Base
s.sayHello();//输出结果为 this is Sub

Sub类通过继承获得say方法,所有通过Sub实例化的对象也同样可以使用该方法。

如果子类的方法与父类方法同名,那么子类的方法会覆盖父类的方法。

class Base {
  say(){
    console.log('this is Base');
  }
}

class Sub extends Base {
  say(){
    console.log('this is Sub');
  }
}

const s = new Sub();
s.say();//输出结果为this is Sub

5,super对象

super对象和this对象类似。this对象表示对象本身,super对象表示本身对象的父类对象。

super对象的使用场景两个:

  • 调用与子类同名的父类方法
  • 调用父类的constructor
class Base {
  say(){
    console.log('this is Base');
  }
}

class Sub extends Base {
  say(){
    //调用父类的say方法
    super.say();
    console.log('this is Sub');
  }
}

const s = new Sub();
s.say();
//输出结果为
this is Base
this is Sub
class Point {
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
}

class Point3D extends Point {
    constructor(x,y,z){
        //调用父类的constructor构造函数
        super(x,y);
        this.z = z;
    }

    logSelf(){
        console.log(`x:${this.x},y:${this.y},z:${this.z}`);
    }
}

const p = new Point3D(1,2,3);
p.logSelf();//输出结果x:1,y:2,z:3

results matching ""

    No results matching ""