ES6 入门

class 的基本语法

简介

类的由来

通过构造函数生成实列对象

  1. 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);

通过class关键字定义类

  1. class Point {
  2. // 构造方法
  3. constructor(x, y) {
  4. this.x = x
  5. this.y = y
  6. }
  7. toString () {
  8. return `${this.x},${this.y}`
  9. }
  10. }
  • ES6 的类 就是构造函数的另一种写法
    1. class Point {
    2. ...
    3. }
    4. // 类的数据类型也是函数
    5. typeof Point // function
    6. //
    7. Point === Point.prototype.constructor // true
  • 类的所有方法都定义在类的prototype属性上

    在类的实列调用方法,其实就是调用原型上的方法

  1. 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. };
  • 类的实列b的constructor方法就是类B原型的constructor方法
    1. class B{}
    2. let b = new B()
    3. b.constructor === B.prototype.constructor
  • prototype 对象的constructor属性,直接指向类本身
    1. Point.prototype.constructor === Point // true

constructor 方法

  • constructor 方法是类的默认方法

  • 通过new命令生成对象实列,自动调用该方法

  • 一个类必须有constructor 方法,没有显示定义的话,一个空的constructor 方法会被默认添加

  • constructor 方法默认返回实列对象

    因此完全可以指定返回一个全新的对象

  1. class Foo {
  2. constructor() {
  3. return Object.create(null);
  4. }
  5. }
  6. new Foo() instanceof Foo // false
  • 类方法 必须使用new命令,不能当作普通方法调用 ```javascript class Foo { constructor() { return Object.create(null); } }

Foo() // TypeError: Class constructor Foo cannot be invoked without ‘new’

  1. <a name="b7a03f8a"></a>
  2. ### 类的实列
  3. -
  4. 实列的属性除非显示的定义在其本身(即定义在this对象上),否则都是定义在原型上
  5. ```javascript
  6. //定义类
  7. class Point {
  8. constructor(x, y) {
  9. this.x = x;
  10. this.y = y;
  11. }
  12. // 定义在了原型对象上
  13. toString() {
  14. return '(' + this.x + ', ' + this.y + ')';
  15. }
  16. }
  17. var point = new Point(2, 3);
  18. point.toString() // (2, 3)
  19. point.hasOwnProperty('x') // true
  20. point.hasOwnProperty('y') // true
  21. point.hasOwnProperty('toString') // false
  22. point.__proto__.hasOwnProperty('toString') // true
  • 所有的实列共享一个原型 ```javascript var p1 = new Point(2,3); var p2 = new Point(3,2);

// 他们的原型都是Point.pototype p1.proto === p2.proto

  1. > 因为原型相同 在一个实列上为原型添加一个方法,其他实列都可以调用
  2. ```javascript
  3. var p1 = new Point(2,3);
  4. var p2 = new Point(3,2);
  5. p1.__proto__.printName = function () { return 'Oops' };
  6. p1.printName() // "Oops"
  7. p2.printName() // "Oops"
  8. var p3 = new Point(4,2);
  9. p3.printName() // "Oops"

取值函数(getter) 和 存值函数 (setter)

  • 对某个属性设置存值函数和取值函数 拦截该属性的存取行为

    prop属性有对应的存值函数和取值函数,因此赋值和读取行为都被自定义了

  1. class MyClass {
  2. constructor() {
  3. // ...
  4. }
  5. get prop() {
  6. return 'getter';
  7. }
  8. set prop(value) {
  9. console.log('setter: '+value);
  10. }
  11. }
  12. let inst = new MyClass();
  13. inst.prop = 123;
  14. // setter: 123
  15. inst.prop
  16. // 'getter'

Class 表达式

  • 类也可以用表达式的形式定义
    1. const MyClass = class Me {
    2. getClassName() {
    3. // Me 只能在内部使用 代指当前类
    4. // 在外部, 这个类只能用MyClass 引用
    5. return Me.name
    6. }
    7. }
  • 采用Class 表达式 可以写出立即执行的class ```javascript const person = new Class { constructor(name) {
    1. this.name = name
    } sayName () {
    1. console.log(this.name)
    } }(‘张三’)

person.sayName() // 张三

  1. <a name="85b97dce"></a>
  2. ### 静态方法
  3. > 类相当于实列的原型,所有在类中定义的方法,都会被实列继承
  4. > 如果在一个方法前,加上staticu关键字,就表示该方法不会被实例继承,而是直接通过类来调用
  5. ```javascript
  6. class Foo {
  7. static classMethod() {
  8. return 'hello';
  9. }
  10. }
  11. Foo.classMethod() // 'hello'
  12. // 只能通过类来调用 通过实例来调用会报错
  13. var foo = new Foo();
  14. foo.classMethod()
  15. // TypeError: foo.classMethod is not a function
  • 如果静态方法包含this关键字 ,这个this指的是类,而不是实例 ```javascript class Foo { static bar () { // 此 this 指向类而不是实例 // 相当于FOO.baz this.baz() }
    static baz () { console.log(‘hello’) } // 静态方法和非静态方法可以重名 baz () { console.log(‘world’) } }

Foo.bar()

  1. -
  2. 父类的静态方法可以被子类继承
  3. ```javascript
  4. class Foo {
  5. static classMethod() {
  6. return 'hello';
  7. }
  8. }
  9. class Bar extends Foo {
  10. }
  11. Bar.classMethod() // 'hello'

静态方法也是可以从super对象上调用的

  1. class Foo {
  2. static classMethod() {
  3. return 'hello';
  4. }
  5. }
  6. class Bar extends Foo {
  7. static classMethod() {
  8. return super.classMethod() + ', too';
  9. }
  10. }
  11. Bar.classMethod() // "hello, too"