ES6系列之class

发布时间:2019-08-09 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了ES6系列之class脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的prototype属性上面。
由于类的方法都定义在PRototyPE对象上面,所以类的新方法可以添加在Prototype对象上面。Object.assign方法可以很方便地一次向类添加多个方法。
prototype对象的constructor属性,直接指向“类”的本身,这与 ES5 的行为是一致的。
另外,类的内部所有定义的方法,都是不可枚举的(non-enumerable)。

1.严格模式
类和模块的内部,默认就是严格模式,所以不需要use strict指定运行模式。只要你的代码写在类或模块之中,就只有严格模式可用。

2.constructor方法
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显示定义,一个空的constructor方法会被默认添加。
类必须使用new调用,否则会报错,这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

3.类的实例对象
生成类的实例对象的写法,与ES5完全一样,也是使用new命令。前面说过,如果忘记加上new,像函数那样调用Class,将会报错。

4.Class表达式

const MyClass = class Me {
  getclassname() {
    return Me.name;
  }
};
let inst = new MyClass();
inst.getClassName() // Me
Me.name // ReferenceError: Me is not defined

如果类的内部没用到的话,可以省略Me,也就是可以写成下面的形式。

const MyClass = class { /* ... */ };

5.不存在变量提升

6.变量提升
类的方法内部如果含有this,它默认指向类的实例。但是,必须非常小心,一旦单独使用该方法,很可能报错。
1)在构造方法中绑定this

class LOGger {
  constructor() {
    this.printName = this.printName.bind(this);
  }

  // ...
}

2)使用箭头函数

class Logger {
  constructor() {
    this.printName = (name = 'there') => {
      this.print(`Hello ${name}`);
    };
  }

  // ...
}

7.name属性
name属性总是返回仅跟在class关键字后面的类名

8.Class的取值函数(getter)和存值函数(setter)
与ES5一样,在“类”的内部可以使用get和set关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。

class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return 'getter';
  }
  set prop(value) {
    console.log('setter: '+value);
  }
}

let inst = new MyClass();

inst.prop = 123;
// setter: 123

inst.prop
// 'getter'

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

class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

VAR foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

注意,如果静态方法包含this关键字,这个this指的是类,而不是实例。
父类的静态方法,可以被子类继承。
静态方法也是可以从super对象上调用的。

10.Class的静态属性和实例属性
静态属性指的是Class本身的属性,即Class.propName,而不是定义在实例对象(this)上的属性。
ES6明确规定,Class内部只有静态方法,没有静态属性。

11.new.target属性
new是从构造函数生成实例对象的命令。如果构造函数不是通过new命令调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的。
Class 内部调用new.target,返回当前 Class。
需要注意的是,子类继承父类时,new.target会返回子类。
利用这个特点,可以写出不能独立使用、必须继承后才能使用的类。

class Shape {
  constructor() {
    if (new.target === Shape) {
      throw new Error('本类不能实例化');
    }
  }
}

class Rectangle extends Shape {
  constructor(length, width) {
    super();
    // ...
  }
}

var x = new Shape();  // 报错
var y = new Rectangle(3, 4);  // 正确

12.继承
1)Class可以通过extends关键字实现继承。

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

  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}

子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。
另一个需要注意的是,在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类实例的构建,基于父类实例,只有super方法才能调用父类实例。
2)Object.getPrototypeOf()方法可以用来从子类上获取父类。因此,可以判断一个类是否继承了另一个类。
3)super关键字
a.第一种情况,super作为函数调用时,代表父类的构造函数。只能在子类的构造函数中调用,否则报错。
b.第二种情况,super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。
4)类的prototype属性和__proto__属性
大多数浏览器的 ES5 实现之中,每一个对象都有__proto__属性,指向对应的构造函数的prototype属性。Class 作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。
a.子类的__proto__属性,表示构造函数的继承,总是指向父类。
b.子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。
子类实例的__proto__属性的__proto__属性,指向父类实例的__proto__属性。也就是说,子类的原型的原型,是父类的原型。

//示例
class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true

//等同于以下实现逻辑
class A {
}

class B {
}

// B 的实例继承 A 的实例
Object.setPrototypeOf(B.prototype, A.prototype);

// B 继承 A 的静态属性
Object.setPrototypeOf(B, A);

const b = new B();

Object.setPrototypeOf = function (obj, proto) {
  obj.__proto__ = proto;
  return obj;
}

脚本宝典总结

以上是脚本宝典为你收集整理的ES6系列之class全部内容,希望文章能够帮你解决ES6系列之class所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。