es6类
es6类与es5类对比
es6和es5的类声明很相似但是也有很多区别:
- 1 es6类声明是没有变量提升和不能重复声明和let一样,也是就说在执行没到达声明前不可以使用
- 2 es6类声明中所有代码自动在严格模式下执行
- 3 es6类声明中的所用的方法都是不可枚举的,在es5中可以使用Object.defineProperty实现
- 4 es6类声明中的所有的方法都缺失内部[[Construct]]属性,也就是说不能当做构造函数使用
- 5 es6类必须使用new调用,否则报错
- 6 不能在es6类声明中修改类名
- 7 es6明确声明class内部只能有静态方法,没有静态属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61//es6 class
class PersonType {
constructor(name){
this.name = name;
}
static sayClassName(){
console.log(this.name);// PersonType
}
sayName(){
console.log(this.name);
}
}
PersonType.family = "chen";
// es5 calss(大部分是es5)
let personType = (function(){
"use strict";
// 确保函数是使用new调用的
const PersonType = function(name){
if(typeof new.target === "undefined"){
throw new Error("构造函数必须使用new调用")
}
this.name = name;
};
Object.defineProperty(PersonType,"sayClassName",{
value: function(){
// 确保原型上的方法不是被new调用
if(typeof new.target !== "undefined"){
throw new Error("Method cannot be called with new.");
}
console.log(this.name)
},
enumerable: false,
writable: true,
configurable: true
});
PersonType.family = "chen";
Object.defineProperty(PersonType.prototype,"sayName",{
value: function(){
// 确保原型上的方法不是被new调用
if(typeof new.target !== "undefined"){
throw new Error("Method cannot be called with new.");
}
console.log(this.name)
},
enumerable: false,
writable: true,
configurable: true
});
return PersonType
}())
es6的一些新应用
私有方法
1 | const sayName = Symbol('sayName'); |
存取函数:实现拦截该属性的存取
1 | // es5 |
这里实现了对原型上html属性的拦截,且这个属性不可枚举,get和set里强制执行严格模式
es6继承
es5和es6继承对比
1 | //ES5 |
这里的es6通过关键字extends来实现继承,通过在contructor里的super()来调用父类的构造函数。
表名上es5和es6继承很相似但实际上大有不同:
- es5中的this是先创造子类的实例对象this,然后再将父类的方法和属性添加到this上。而es6则刚好相反。
- es5中一般只实现了子类原型对父类构造函数原型的继承也就是单链继承,es6中不但实现了es5中继承还实现了子类构造函数对父类构造函数的继承,这就是说子类构造函数可以使用父类构造函数上的静态方法,结果上来说是双链继承。
1
2console.log( Square.__proto__ === Rectangle); // true
console.log( Square.prototype.__proto__ === Rectangle.prototype ); // true
es6继承注意项
constuctor
constructor可以省略:
1 | class Square extends Rectangle{ |
constructor不省略时:
- super()只能在继承子类constructor里使用
- super()必须调用来创造this,除非直接从constructor中返回一个对象
- 因为super()是用来初始化this的,在super()调用之前不能使用this
super关键字
super关键字既可以当做函数使用也可以当做对象使用,这两种情况完全不一样,且在出现关键字super时必须明确super是对象或者函数否则会报错。
super函数:
- 作为父类的构造函数,子类构造函数中一般必须执行一次super函数,具体使用如上
- 在super()执行时内部的this默认指向子类
1
2
3
4
5
6
7
8
9
10
11
12
13class A{
constructor(){
console.log(new.target.name);
}
}
class B extends A{
constructor(){
super();
}
}
new A(); // A
new B(); // B
super对象:
- 在普通方法中,指向父类原型对象;在静态方法中指向父类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class A {
p() {
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); // 2
}
p(){
return 1;
}
}
let b = new B(); - 同样super当做对象时this默认指向子类
- super.x = 3 相当于this.x = 3