ES6新增class(类)优化的构造函数的写法:
class Obj {
constructor (str1){
this.a = str1
}
printA (){
console.log(this.a)
}
}
var obj = new Obj('a')
obj.printA() // a
相当于:
function Obj (str1){
this.a = str1
}
Obj.prototype.printA (){
console.log(this.a)
}
var obj = new Obj('a')
obj.printA() // a
从上面的代码可以看出,在class 内声明的内容,相当于声明在function的prototype中,也因此在class内constructor中声明的内容,相当于声明在function中(function的prototype的constructor即函数自身)。当声明一个空的class时,其constructor方法会被默认添加。
关于class还有其他语法:
getter和setter
class Obj {
constructor (str) {
this.a = str
}
get a (){
return this._a
}
set a (str){
this._a = 'this is ' + str
}
printA(){
console.log(this.a)
}
}
var obj = new Obj('a')
obj.printA() // this is a
obj.a = 'aaa'
obj.printA() // this is aaa
使用class的getter和setter时应注意:
- 一个属性的get方法和set方法必须成对出现,如果只定义getter不定义对应setter会抛出typeError错误,如果不定义getter只定义setter虽然不会报错但该属性将无法获取。
- 在get/set方法内部不能通过this.属性名使用该属性,必须在属性名前加_(下划线)才能使用。
- 如果定义了set方法,则在创建新实例时通过constructor进行初始化赋值也将通过调用set方法实现。
静态方法/属性
class Obj {
constructor (str) {
this.a = str
}
get a (){
return this._a
}
set a (str){
this._a = 'this is ' + str
}
printA(){
console.log(this.a)
}
static printB(){
console.log(this.b)
}
}
Obj.b = 'b'
Obj.printB() // b
var obj = new Obj('a')
obj.b // undifined
obj.printB() // 报错
使用class的静态方法/属性时应注意:
- 使用class创建实例时,实例不能继承静态方法/属性。
- 在class的静态方法内部,this指向该class自身,不指向创建的实例。
- 在class内通过static声明方式只能定义静态方法,不能定义静态属性(ES6 规定:Class 内部只有静态方法,没有静态属性)。如果要定义静态属性只能通过对该class进行属性赋值操作实现(如:Obj.b = 'b')。
- 虽然静态方法和属性不能被实力继承,但是子类可以继承父类的静态属性和方法,如下:
class Obj1 {
constructor (str) {
this.a = str
}
get a (){
return this._a
}
set a (str){
this._a = 'this is ' + str
}
printA(){
console.log(this.a)
}
static printB(){
console.log(this.b)
}
}
Obj.b = 'b'
class Obj2 extends Obj1 {}
Obj2.b // b
Obj2.printB() // b
通过上面的代码可以看出Obj2继承了Obj1的静态属性和静态方法,同时也可以看出ES6中class的继承语法,即通过extends关键字实现父类子类继承。
使用ES6 的 class 定义类 不存在变量提升。