关灯
开启左侧

ES6-class基本语法

[复制链接]
紫米 发表于 2018-12-13 10:02:42 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
 
ES5中,生成实例对象的传统方法是通过构造函数:
  1. <font color="#000000" style="background-color: white;">function Point(x, y) {
  2.   this.x = x;
  3.   this.y = y;
  4. }

  5. Point.prototype.toString = function () {
  6.   return '(' + this.x + ', ' + this.y + ')';
  7. };

  8. var p = new Point(1, 2);</font>
复制代码
上面这种写法跟传统的面向对象语言(比如 C++ 和 Java)差异很大。
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样去定义类。
  1. <font color="#000000" style="background-color: white;">class Point {
  2.   constructor(x, y) {
  3.     this.x = x;
  4.     this.y = y;
  5.   }

  6.   toString() {
  7.     return '(' + this.x + ', ' + this.y + ')';
  8.   }
  9. }</font>
复制代码
上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。也就是说,ES5 的构造函数Point,对应 ES6 的Point类的构造方法。
Point类除了构造方法,还定义了一个toString方法。注意,定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了。另外,方法之间不需要逗号分隔,加了会报错。
ES6 的类,完全可以看作构造函数的另一种写法。
  1. <font color="#000000" style="background-color: white;">class Point {
  2.   // ...
  3. }

  4. typeof Point // "function"
  5. Point === Point.prototype.constructor // true</font>
复制代码
上面代码表明,类的数据类型就是函数,类本身就指向构造函数。
使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致。
  1. <font color="#000000" style="background-color: white;">class Bar {
  2.   doStuff() {
  3.     console.log('stuff');
  4.   }
  5. }

  6. var b = new Bar();
  7. b.doStuff() // "stuff"</font>
复制代码
构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。
  1. <font color="#000000" style="background-color: white;">class Point {
  2.   constructor() {
  3.     // ...
  4.   }

  5.   toString() {
  6.     // ...
  7.   }

  8.   toValue() {
  9.     // ...
  10.   }
  11. }

  12. // 等同于

  13. Point.prototype = {
  14.   constructor() {},
  15.   toString() {},
  16.   toValue() {},
  17. };</font>
复制代码
在类的实例上面调用方法,其实就是调用原型上的方法。
  1. <font color="#000000" style="background-color: white;">class B {}
  2. let b = new B();

  3. b.constructor === B.prototype.constructor // true</font>
复制代码
上面代码中,b是B类的实例,它的constructor方法就是B类原型的constructor方法。
由于类的方法都定义在prototype对象上面,所以类的新方法可以添加在prototype对象上面。Object.assign方法可以很方便地一次向类添加多个方法。
  1. <font color="#000000" style="background-color: white;">class Point {
  2.   constructor(){
  3.     // ...
  4.   }
  5. }

  6. Object.assign(Point.prototype, {
  7.   toString(){},
  8.   toValue(){}
  9. });</font>
复制代码
prototype对象的constructor属性,直接指向“类”的本身,这与 ES5 的行为是一致的。
  1. <font color="#000000" style="background-color: white;">Point.prototype.constructor === Point // true</font>
复制代码
另外,类的内部所有定义的方法,都是不可枚举的(non-enumerable)
  1. <font color="#000000" style="background-color: white;">class Point {
  2.   constructor(x, y) {
  3.     // ...
  4.   }

  5.   toString() {
  6.     // ...
  7.   }
  8. }

  9. Object.keys(Point.prototype)
  10. // []
  11. Object.getOwnPropertyNames(Point.prototype)
  12. // ["constructor","toString"]</font>
复制代码
上面代码中,toString方法是Point类内部定义的方法,它是不可枚举的。这一点与 ES5 的行为不一致。
  1. <font color="#000000" style="background-color: white;">var Point = function (x, y) {
  2.   // ...
  3. };

  4. Point.prototype.toString = function() {
  5.   // ...
  6. };

  7. Object.keys(Point.prototype)
  8. // ["toString"]
  9. Object.getOwnPropertyNames(Point.prototype)
  10. // ["constructor","toString"]</font>
复制代码
上面代码采用 ES5 的写法,toString方法就是可枚举的。
类的属性名,可以采用表达式。
  1. <font color="#000000" style="background-color: white;">let methodName = 'getArea';

  2. class Square {
  3.   constructor(length) {
  4.     // ...
  5.   }

  6.   [methodName]() {
  7.     // ...
  8.   }
  9. }</font>
复制代码
上面代码中,Square类的方法名getArea,是从表达式得到的。


 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

排行榜
关闭

站长推荐上一条 /1 下一条

官方微信

全国服务热线:

400-9988-316

公司地址:国家西部信息安全产业基地(成都市高新区云华路333号)

邮编:610000    Email:2908503813@qq.com

Copyright   ©2015-2016  EOIT论坛Powered by©Discuz!    ( 蜀ICP备11000634号-7 )