var A = class{ test(){} } class A{ test(){} } 这两种写法有什么区别,用起来有什么区别,面试被问道了,不会,很尴尬
没区别啊。。。。。。。。。
前者有变量提升,后者没有
前者是匿名类,后者有名字。
@lizhenwu 变量提升是 ES5里面的 函数才有 ES6的 class 不会提升
前者是类表达式(ClassExpression)+赋值表达式(AssignmentExpression ),后者是类声明(ClassDeclaration)。
类表达式:
ClassExpression[Yield, Await]:
classBindingIdentifier[?Yield, ?Await] opt ClassTail [?Yield, ?Await]
类声明:
ClassDeclaration[Yield, Await, Default]:
classBindingIdentifier[?Yield, ?Await] ClassTail [?Yield, ?Await]
[+Default] classClassTail [?Yield, ?Await]
从规范中可以看出,前者的类名(classBindingIdentifier)可以省略,而后者不行。
class {} // 类声明: SyntaxError: Unexpected token {
var A = class {} // 类表达式: √
对于类声明,只有一种情况可以省略类名,就是在 export 语句中:
ClassDeclaration:
class ClassTail
only occurs as part of an ExportDeclaration and the setting of a name property and establishing its binding are handled as part of the evaluation action for that production.
export default class {}; // √ 类声明
关于变量提升,其实类声明和函数声明不同,类声明不存在变量提示。
new A();
class A{};
// ReferenceError: A is not defined
fn();
function fn(){};
// √
只所以 class 和 function 的提示规则不同,是因为 class 还涉及到了继承。考虑如下代码,如果存在类声明的变量提升,那么:
let A = class{}; // 不提示
class B extends A{} // 提示
第一行代码是类表达式,不提示。第二行是类声明,如果把第二行提升了,那么就会报错,因为 A 还未定义。