有过JavaScript开发经历的小伙伴们肯定都知道,class
这个关键字一直以来都是作为系统保留字而不允许使用。而在ES6中,class
关键字终于排上了用场。
类
虽然说JavaScript也正儿八经是一个面向对象的语言,但很长一段时间以来JavaScript中的类一直都是“有实无名”。
说“有实”是因为在ES6之前的标准中我们可以通过函数跟原型来实现大部分“类”的功能和概念。说“无名”是因为,这确实不能称得上是传统类的概念。
而事实上,ES6class
也只是一个语法糖。但是新的class
写法可以让类的定义、继承更加的清晰,语法更加的面向对象。
在ES6以前,定义一个类如下:
function Foo(x,y){
this.x = x;
this.y = y;
}
Foo.prototype.sayX = function(){
console.log(this.x);
}
而用class
改写之后如下:
class Foo{
constructor(x, y){
this.x = x;
this.y = y;
}
sayX(){
console.log(this.x);
}
}
Foo
这个类中的constructor
方法便是构造方法,它对应旧的写法中的Foo
函数。
除了构造函数,Foo
类中还定义了一个sayX
方法,定义方法的时候前面不需要加入“function”,加了是会报错的。方法与方法之间也不需要加逗号,加了也会报错
因为class
就是一个语法糖,所以ES6的类实质上仍然是函数,也具有原型。
可以看出class
与ES6之前的构造函数在行为上有许多相似。
也有不同点,使用class
定义的类使用时前面必须加new
关键字,否则会报错。
实例的构造
当使用new
命令实例化一个类的时候,会自动调用类声明中的constructor
方法。一个类必须得有一个constructor
方法,若没有显式声明,则会默认添加一个空白的constructor
方法。
类表达式
JavaScript中函数表达式,即let foo = function(){}
这样的形式。而类也同样能用表达式的形式定义。
let newClass = class self{
getNmae(){
return self.name;
}
}
上面就使用类表达式的方法定义了一个类,虽然说这个累的名字是self
,但是self
也只能在类的内部可用,用来指代当前类,在类的外部只能通过newClass
来使用它。
注:类名亦可省略,若内部不需要指向自己
类的静态方法
在很多语言中,在方法前面加个static
就会使该方法变为静态,成为只能通过类来调用的类方法。
而在ES6中也加入了类似的特性,例如:
class Foo{
static test(){
console.log(this === Foo);
}
}
上面代码中定义了一个名为test
的静态方法,该方法的执行结果是输出了true
。这说明了,在静态方法内部的this
指向的是类自己。
静态方法不会被实例继承,如果实例去调用静态方法则会报错。
与构造函数的不同点
- 在类的内部默认是严格模式。
- 类不存在函数提升。这一点与ES6之前的版本非常不同,这是因为要照顾到继承,必须保证子类在父类之后定义。