Class基础知识
语法:
1 | // 方法一 Class声明 |
类的数据类型是函数,因为类本身指向构造函数,类的方法都定义在prototype属性上面,可以使用Object.assign方法一次向类添加多个方法
!注意:
1.在类的实例上调用方法,就是调用原型上的方法
2.prototype对象的constructor属性直接指向类本身
3.类的内部所有定义的方法都是不可枚举的
4.类默认有constructor方法,如果没有显示定义,空的constructor方法会被默认添加
5.constructor方法默认返回实例对象(即this),完全可以指定返回另外一个对象
6.Class的name属性总是返回类名
1 | class Point { |
6.类必须使用new调用
敲黑板!!!划重点!!!
实例的属性除非显示定义在this对象上,否则都是定义在原型(class)上,即实例的自身属性都定义在this变量上,实例共享的属性和方法都定义在原型对象上也就是类上。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var point = new Point(2, 3);
point.toString() // (2, 3)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true类的所有实例共享一个原型对象,也就是说可以通过实例的proto属性为class添加方法。不过,因为通过实例的proto属性改写原型会改变class的原始定义,会影响到所有实例,需注意!
1 | var p1 = new Point(2,3); |
proto不是语言本身特性,而是各大厂商实现的私有属性,不建议在生产环境中使用该属性,建议使用Object.getPrototypeOf方法来获取实例对象的原型,然后再添加源性方法/属性。
类不存在变量提升,必须保证子类在父类之后定义
私有方法的实现:
1.方法名前加下划线(不保险),类的外部还是可以调到这个方法
2.将私有方法移出模块(因为模块内部的方法都是对外可见的)
3.利用Symbol值的唯一性,将私有方法的名字命名为一个Symbol值
私有属性的提案:
1.使用#在属性名之前,使用时必须带有#一起使用
2.私有属性可以指定初始值,在构造函数时进行初始化
- #设置私有属性,也可以设置私有方法
- 私有属性也可以设置getter和setter方法
this指向:类的方法内部如果使用this,则默认指向类的实例,但是单独使用这个方法时,this会指向该方法运行时所在的环境,此时会因为找不到绑定对象而报错
- 解决方法:
- 构造方法中指定this(最推荐!)
- 使用箭头函数
- 使用Proxy(未使用,详见ES6文档)
- 解决方法:
Class的取值函数(getter)和存值函数(setter)是设置在属性的Descriptor对象上的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20class CustomHTMLElement {
constructor(element) {
this.element = element;
}
get html() {
return this.element.innerHTML;
}
set html(value) {
this.element.innerHTML = value;
}
}
var descriptor = Object.getOwnPropertyDescriptor(
CustomHTMLElement.prototype, "html"
);
"get" in descriptor // true
"set" in descriptor // trueClass内部的方法前加上*,即为一个Generator函数(emmmmm,是时候又回去看看generator啦~)
Class的静态方法:
- 语法:static methodName() {}
- 可以在类上调用,但是不能在实例上调用。如果静态方法中指定了this,则指向类。
- 静态方法可以与非静态方法重名。
- 父类的静态方法可以被子类继承,也可以从super对象上调用的。
Class的静态属性和实例属性:
- 静态属性指的是类本身的属性,而不是this上的属性
- 类的实例属性可以用等式写在类的定义中
1
2
3
4
5
6
7class MyClass {
myProp = 42;
constructor() {
console.log(this.myProp); // 42
}
}
* 类的静态属性是在实例属性写法前面加上static关键字
1
2
3
4
5
6
7
8
9
10
// 老写法
class Foo {
// ...
}
Foo.prop = 1;
// 新写法
class Foo {
static prop = 1;
}