0%

es6 学习笔记 2

Class

  • 不存在变量提升
  • 构造函数的 prototype 属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的 prototype 属性上面。
  • prototype 对象的 constructor 属性,直接指向“类”的本身,constructor()方法默认返回实例对象(即 this),完全可以指定返回另外一个对象。

类的实例

  • 与 ES5 一样,实例的属性除非显式定义在其本身(即定义在 this 对象上),否则都是定义在原型上(即定义在 class 上)。与 ES5 一样,类的所有实例共享一个原型对象。

Class 表达式

与函数一样,类也可以使用表达式的形式定义。

1
2
3
4
5
const MyClass = class Me {
getClassName() {
return Me.name;
}
};

上面代码表示,Me 只在 Class 内部有定义。
采用 Class 表达式,可以写出立即执行的 Class。

1
2
3
4
5
6
7
8
9
10
11
let person = new (class {
constructor(name) {
this.name = name;
}

sayName() {
console.log(this.name);
}
})("张三");

person.sayName(); // "张三"

上面代码中,person 是一个立即执行的类的实例。

静态方法

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

实例属性的新写法

  • 实例属性除了定义在 constructor()方法里面的 this 上面,也可以定义在类的最顶层,这时不需要在之前加 this。

静态属性

  • 静态属性指的是 Class 本身的属性,即 Class.propName,而不是定义在实例对象(this)上的属性。
1
2
3
4
class Foo {}

Foo.prop = 1;
Foo.prop; // 1

new.target 属性

new 是从构造函数生成实例对象的命令。ES6 为 new 命令引入了一个 new.target 属性,该属性一般用在构造函数之中,返回 new 命令作用于的那个构造函数。如果构造函数不是通过 new 命令或 Reflect.construct()调用的,new.target 会返回 undefined,因此这个属性可以用来确定构造函数是怎么调用的。

1
2
3
4
5
6
7
8
9
class Rectangle {
constructor(length, width) {
console.log(new.target === Rectangle);
this.length = length;
this.width = width;
}
}

var obj = new Rectangle(3, 4); // 输出 true

子类继承父类时,new.target 会返回子类。

Object.getPrototypeOf()

用于获取父类

super

有两种用法 当做函数代表父类的构造函数,当做对象,在普通方法中,指向父类的原型对象,在静态方法中指向父类
需要注意的是,由于 super 指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过 super 调用的。在子类普通方法中通过 super 调用父类的方法时,方法内部的 this 指向当前的子类实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A {
constructor() {
this.x = 1;
}
print() {
console.log(this.x);
}
}

class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.print();
}
}

let b = new B();
b.m(); // 2

继承链

  • 1 子类的proto属性,表示构造函数的继承,总是指向父类。
  • 2 子类 prototype 属性的proto属性,表示方法的继承,总是指向父类的 prototype 属性。