JavaScript中类赋值变量与常规类定义的含义及差异解析
嘿,我来给你掰扯清楚这两段代码的门道哈!首先直接给你答案:const something = class extends anything { }这段代码确实把类存储到了变量something里,它属于「类表达式」,和常规的「类声明」class something extends anything { }有不少关键区别,我给你一一拆解:
核心含义先搞懂
对于
const something = class extends anything { }:
你可以把它类比成const fn = function() {}这种函数表达式——先创建一个继承自anything的类,再把这个类的引用赋值给变量something。这个类本身可以是匿名的(就像例子里这样),也可以给它加个内部名字(比如const something = class MyInnerClass extends anything { },但外部只能通过something访问它)。对于
class something extends anything { }:
这是标准的类声明,直接在当前作用域下定义一个名为something、继承自anything的类,和函数声明的写法逻辑一致。
关键区别对比
变量提升与暂时性死区:
类声明会被「提升」到作用域顶部,但处于暂时性死区(TDZ)——也就是说,如果你在声明前就访问something,会直接抛出ReferenceError;而类表达式依托变量赋值,const变量本身也在TDZ里,所以在赋值前访问同样会报错,但本质是变量的TDZ限制,而非类本身的提升特性。作用域控制:
类声明的作用域是当前的块级/全局作用域(比如在函数里声明的类,整个函数都能访问);而类表达式的作用域完全由变量something的作用域决定——比如把它写在函数内部,外部根本访问不到something这个变量,自然也用不了这个类。命名灵活性:
类声明必须有一个明确的名字(就是class后面的标识符);但类表达式可以是匿名的(像例子里那样),也可以只给类加内部名字(方便在类内部递归调用或者查看constructor.name),外部完全不用关心这个内部名字。使用场景的灵活性:
类表达式可以像普通值一样传递——比如作为参数传给函数、作为对象的属性值,甚至在条件判断里动态创建(虽然这种写法不推荐,但语法上是合法的);而类声明不能放在条件语句里,因为不同JavaScript环境对块级作用域里的类声明处理有差异,容易出bug。
内容的提问来源于stack exchange,提问作者Alwaysblue

