ES6深入—ES6 Class 类


class ExampleD {

  a = 2;

  constructor() {

    console.log(this.a);

  }

}



name 属性

返回跟在 class 后的类名(存在时)。


let ExampleE = class Exam {

  constructor(a) {

    this.a = a;

  }

};

console.log(ExampleE.name); // Exam



let ExampleF = class {

  constructor(a) {

    this.a = a;

  }

};

console.log(ExampleF.name); // ExampleF



实例:

创建名称为 test2.js 的文件,并且输入下面的代码。


// 静态属性



class ExampleA {

  // 新提案

  static a = 3;

}

// 目前可行写法

ExampleA.b = 3;



// 公共属性

class ExampleB {}

ExampleB.prototype.a = 2;

// 实例属性

class ExampleC {

  a = 2;

  constructor() {

    console.log(this.a);

  }

}



// name 属性

let ExampleD = class ExamD {

  constructor(a) {

    this.a = a;

  }

};

console.log(ExampleD.name); // Exam



let ExampleE = class {

  constructor(a) {

    this.a = a;

  }

};

console.log(ExampleE.name); // Example



在终端运行,结果如下所示:

请添加图片描述

三、方法

=======================================================================

constructor 方法

constructor 方法是类的默认的方法,创建类的实例化对象时被调用。


class Example {

  constructor() {

    console.log("我是constructor");

  }

}

new Example(); // 我是 constructor



返回对象


class Test {

  constructor() {

    // 默认返回实例对象 this

  }

}

console.log(new Test() instanceof Test); // true



class Example {

  constructor() {

    // 指定返回对象

    return new Test();

  }

}

console.log(new Example() instanceof Example); // false



静态方法


class Example {

  static sum(a, b) {

    console.log(a + b);

  }

}

Example.sum(1, 2); // 3



原型方法


class Example {

  constructor() {

    this.sum = (a, b) => {

      console.log(a + b);

    };

  }

}



实例方法


class Example {

  constructor() {

    this.sum = (a, b) => {

      console.log(a + b);

    };

  }

}



实例:

创建名称为 test3.js 的文件,并且输入下面的代码。


// constructor 方法



class Example {

  constructor() {

    console.log("我是constructor");

  }

}

new Example(); // 我是 constructor



// 返回对象



class Test {

  constructor() {

    // 默认返回实例对象 this

  }

}

console.log(new Test() instanceof Test); // true



class ExampleB {

  constructor() {

    // 指定返回对象

    return new Test();

  }

}

console.log(new Example() instanceof ExampleB); // false



// 静态方法



class ExampleD {

  static sum(a, b) {

    console.log(a + b);

  }

}

ExampleD.sum(1, 2); // 3



// 原型方法

class ExampleE {

  constructor() {

    this.sum = (a, b) => {

      console.log(a + b);

    };

  }

}



// 实例方法

class ExampleF {

  constructor() {

    this.sum = (a, b) => {

      console.log(a + b);

    };

  }

}



在终端运行,结果如下所示:

请添加图片描述

四、类的实例化

==========================================================================

new

类的实例化,必须通过 new 关键字。


class ExampleG {}



let exam1 = ExampleG();

// Class constructor Example cannot be invoked without 'new'



实例化对象

共享原型对象。


class ExampleH {

  constructor(m, n) {

    this.m = m;

    this.n = n;

    console.log("ExampleH");

  }

  sum() {

    return this.m + this.n;

  }

}

let exam1 = new ExampleH(5, 3);

let exam2 = new ExampleH(2, 7);

console.log(exam1._proto_ == exam2._proto_); // true



exam1.__proto__.sub = function () {

  return this.a - this.b;

};

console.log(exam1.sum()); // 8

console.log(exam2.sum()); // 9



实例:

创建名称为 test4.js 的文件,并且输入下面的代码。


class ExampleH {

  constructor(m, n) {

    this.m = m;

    this.n = n;

    console.log("ExampleH");

  }

  sum() {

    return this.m + this.n;

  }

}

let exam1 = new ExampleH(5, 3);

let exam2 = new ExampleH(2, 7);

console.log(exam1._proto_ == exam2._proto_); // true



exam1.__proto__.sub = function () {

  return this.a - this.b;

};

console.log(exam1.sum()); // 8

console.log(exam2.sum()); // 9



在终端运行,结果如下所示:

请添加图片描述

五、decorator

==============================================================================

decorator 是一个函数,用来修改类的行为,在代码编译时产生作用。

类修饰

一个参数。

第一个参数 target,指向类本身。


function testable(target) {

  target.isTestable = true;

}

@testable

class Example {}

Example.isTestable; // true



多个参数——嵌套实现。


function testable(isTestable) {

  return function (target) {

    target.isTestable = isTestable;

  };

}

@testable(true)

class Example {}

Example.isTestable; // true



实例属性,上面两个例子添加的是静态属性,若要添加实例属性,在类的 prototype 上操作即可。

方法修饰

3 个参数:target(类的原型对象)、name(修饰的属性名)、descriptor(该属性的描述对象)。


class Example {

  @writable

  sum(a, b) {

    return a + b;

  }

}

function writable(target, name, descriptor) {

  descriptor.writable = false;

  return descriptor; // 必须返回

}



修饰器执行顺序

由外向内进入,由内向外执行。


class Example {

  @logMethod(1)

  @logMthod(2)

  sum(a, b) {

    return a + b;

  }

}

function logMethod(id) {

  console.log("evaluated logMethod" + id);

  return (target, name, desctiptor) =>

    console.log("excuted         logMethod " + id);

}

// evaluated logMethod 1

// evaluated logMethod 2

// excuted logMethod 2

// excuted logMethod 1



六、封装与继承

==========================================================================

getter / setter

定义如下所示:


class Example {

  constructor(a, b) {

    this.a = a; // 实例化时调用 set 方法

    this.b = b;

  }

  get a() {

    console.log("getter");

    return this.a;

  }

  set a(a) {

    console.log("setter");

    this.a = a; // 自身递归调用

  }

}

let exam = new Example(1, 2); // 不断输出 setter,最终导致 RangeError

class Example1 {

  constructor(a, b) {

    this.a = a;

    this.b = b;

  }

  get a() {

    console.log("getter");

    return this._a;

  }

  set a(a) {

    console.log("setter");

    this._a = a;

  }

}

let exam1 = new Example1(1, 2); // 只输出 setter, 不会调用 getter 方法

console.log(exam._a); // 1, 可以直接访问



创建 名称为 test5.js 的文件,并且输入下面的代码。


class Example {

  constructor(a, b) {

    this.a = a; // 实例化时调用 set 方法

    this.b = b;

  }

  get a() {

    console.log("getter");

    return this.a;

  }

  set a(a) {

    console.log("setter");

    this.a = a; // 自身递归调用

  }

}

let exam = new Example(1, 2); // 不断输出 setter,最终导致 RangeError

class Example1 {

  constructor(a, b) {

    this.a = a;

    this.b = b;

  }

  get a() {

    console.log("getter");

    return this._a;

  }

  set a(a) {

    console.log("setter");

    this._a = a;

  }

}

let exam1 = new Example1(1, 2); // 只输出 setter, 不会调用 getter 方法

console.log(exam._a); // 1, 可以直接访问



在终端输入 node test5.js 运行,结果如下所示:

请添加图片描述

  • 特殊情况:getter 不可单独出现。

class Example {

  constructor(a) {

    this.a = a;

  }

  get a() {

    return this.a;

  }

}

let exam = new Example(1); // Uncaught TypeError: Cannot set property // a of #<Example> which has only a getter



  • 要点:getter 与 setter 必须同级出现。

class Father {

  constructor() {}

  get a() {

    return this._a;

  }

}

class Child extends Father {

  constructor() {

    super();

  }

  set a(a) {

    this._a = a;

  }

}

let test = new Child();

test.a = 2;

console.log(test.a); // undefined



class Father1 {

  constructor() {}

  // 或者都放在子类中

  get a() {

    return this._a;

  }

  set a(a) {

    this._a = a;

  }

}

class Child1 extends Father1 {

  constructor() {

    super();

  }

}

let test1 = new Child1();

test1.a = 2;

console.log(test1.a); // 2



创建名称为 test6.js 的文件,并且输入上面的代码。

在终端输入 node test6.js 后运行,结果如下所示:

请添加图片描述

extends

通过 extends 实现类的继承。


class Child extends Father { ... }



七、super

==========================================================================

子类 constructor 方法中必须有 super,且必须出现在 this 之前,下面的代码就是没有 super 函数导致出错的情况。


class Father {

  constructor() {}

}

class Child extends Father {

  constructor() {}

  // or

  // constructor(a) {

  // this.a = a;

  // super();  // 这里必须要有,如果没有super()会报错

  // }

}

let test = new Child(); // Uncaught ReferenceError: Must call super

// constructor in derived class before accessing 'this' or returning

// from derived constructor



注意要点

不可继承常规对象。


var Father = {

  // ...

};

class Child extends Father {

  // ...

}

// Uncaught TypeError: Class extends value #<Object> is not a constructor or null



// 解决方案

Object.setPrototypeOf(Child.prototype, Father);



创建名称为 test7.js 的文件,并且输入下面的代码。




class Father {

  constructor() {}

}

class Child extends Father {

  constructor(a) {

    super();

    this.a = a;

    console.log(a); // print 12

  }

}

let test = new Child(12);

test;

在终端输入 node test7.js 运行,结果如下所示:

![请添加图片描述](https://img-blog.csdnimg.cn/4509b3f5e73e4cf197c4235c9d0a5406.png)

# 总结

本文介绍了 ES6 Class 的 ES6 类的定义及使用的 constructor() 方法、Class 表达式和 super 关键字。



下文讲解ES6 Generator 函数。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值