ES6之Class详解篇

1.类简介

ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法。
类的数据类型就是函数,类本身就指向构造函数。
使用的时候,也是直接对类使用new命令,跟构造函数的用法完全一致。

2.Class的基本语法

class Point {
  constructor(x,y){
    this.x = x;
    this.y = y;
  }
  toString(){
     return `${this.x},${this.y}`
  }
}

1.ES6写法定义了一个类,可以看到Point类里面有个constructor方法(构造方法)----ES5的构造函数Point,就对应的是ES6的Point类的构造方法

2.Point类中我们还看到了toString方法。注意,定义类的方法的时候,在方法前不要加function关键字,直接把函数定义放进去即可。还需要注意一点,方法之间是不能用逗号分隔的,否则会报错。

ES6的类,完全可看作构造函数的另一种写法(在类的实例上面调用方法,其实就是调用原型上的方法)

构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。

class Point {
  constructor() {
    // ...
  }

  toString() {
    // ...
  }

  toValue() {
    // ...
  }
}

// 等同于

Point.prototype = {
  constructor() {},
  toString() {},
  toValue() {},
};

由于类的方法都定义在prototype对象上,所以类的新方法可以添加在protype对象上面:

class Point {
  constructor(){
    // ...
  }
Object.assign(Point.protype,{
  toValue(){},
  toString(){}
  })
}

3.静态方法

类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。

class Say {
  static sayHello() {
    return 'Hello World!';
  }
}

Say.sayHello() 

var say = new Say();
say.sayHello()
// TypeError: say.sayHello is not a function

注意,如果静态方法包含this关键字,这个this指的是类,而不是实例

class Say {
  static fa() {
    this.fa_s();
  }
  static fa_s() {
    console.log('hello');
  }
  fa_s() {
    console.log('world');
  }
}

Say.bar() // hello

虽然类的静态方法不可被实例所继承,但是却可以被子类继承。

4.实例属性的新写法

实例属性除了定义在constructor()方法里面的this上面,也可以定义在类的最顶层。写法对比:
//实例属性this._count定义在constructor()方法里面

class IncreasingCounter {
  constructor() {
    this._count = 0;
  }
  get value() {
    console.log('Getting the current value!');
    return this._count;
  }
  increment() {
    this._count++;
  }
}
//属性定义在类的最顶层,其它不变
class IncreasingCounter {
  _count = 0;
  get value() {
    console.log('Getting the current value!');
    return this._count;
  }
  increment() {
    this._count++;
  }
}

这种新写法的好处是,所有实例对象自身的属性都定义在类的头部,看上去比较整齐,一眼就能看出这个类有哪些实例属性。

5.静态属性

静态属性指的是 Class 本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
ES6 明确规定,Class 内部只有静态方法,没有静态属性。现在有一个提案提供了类的静态属性,写法是在实例属性法的前面,加上static关键字。

// 老写法
class Foo {
  // ...
}
Foo.prop = 1;

// 新写法
class Foo {
  static prop = 1;
}

6.类的继承

Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
1.子类必须在constructor方法中调用super方法
这是因为子类自己的this对象,必须通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后对其加工,加上子类自己的实例属性和方法,如果不调用super方法,子类就得不到this对象。

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }
  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

2.父类的静态方法,也会被子类继承

class A {
  static hello() {
    console.log('hello world');
  }
}

class B extends A {
}

B.hello()  // hello world

3.Object.propotypeOf()
Object.propotypeOf方法可以用来从子类上获取父类。
使用这个方法判断一个类是否继承了另一个类,

Object.propotypeOf(colorPoint) === Point
//true

4.super关键字
super这个关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同.

第一种情况,super作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次super函数。

第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

5.类的prototype属性和_proto_属性

子类的_prop_属性,表示构造函数的继承,总是指向父类。

子类prototype属性的_prop_属性,表示方法的继承,总是指向父类的prototype属性。

class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
  • 25
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值