尽管ECMAScript 6(简称ES6)引入了类这一特性,表面上看似为JavaScript添加了标准的面向对象编程支持,但其底层机制实际上还是基于原型和构造函数的理念来实现的。
类的定义方式
如同函数一样,定义一个类主要有两种途径:类声明和类表达式。无论是哪一种方式,都需要使用class
关键字配合一对大括号来完成。
- 类声明:直接使用
class
后面跟类名的方式声明一个类。
class Person {}
- 类表达式:通过将类定义赋值给一个变量,达到以表达式形式定义类的目的。这种方式下,类直到表达式被求值时才可被访问。
const Animal = class {};
与函数表达式相似,类表达式在执行到它们所在的代码行之前也是不可见的。尽管函数声明具有提升(hoisting)特性,即可以在声明之前调用,类定义则不具备这种行为,不能被提前使用。
作用域差异
类与函数在作用域处理上也存在显著差异:
- 函数声明:属于函数作用域,在一个函数内部定义的函数可以在该函数的任何地方被访问。
function FunctionDeclaration() {}
- 类声明:则遵循块级作用域规则,如果类在一个块(例如大括号内)中定义,那么这个类只在该块内部可见。
{
class ClassDeclaration {}
}
console.log(ClassDeclaration); // 这里会报错,因为ClassDeclaration仅在块内部有效
尝试在块外访问通过类声明定义的ClassDeclaration
,会得到一个引用错误,提示该类未定义。因为与函数不同,类没有被提升至包含它们的块之外的作用域中。