我有一个有关JavaScript的问题。当我声明新变量并将其分配给类的新实例时,如果抛出错误的变量完全无法使用。
代码下面的代码应抛出错误
class MyClass {
constructor (config) {
this.someProperty = config.someProperty || '';
}
}
let myClassInstance = new MyClass();
如果我尝试为其分配某些内容,JavaScript会丢下错误。
myClassInstance = '123'
未介绍的参考:未定义的myclassinstance
然后我尝试定义变量
let myClassInstance = '123'
uckulting语法:标识符" myclassinstance"已经被声明为
变量也无法删除。我们可以解决这个问题吗?我只是好奇,当然,我会处理未定义为config的构造函数。
编辑:我还尝试使用var,然后可以重复使用myclassinstance。我想知道为什么我使用该变量是否无法删除,声明或新值无法重新分配。
编辑2:我可以处理传递未定义或传递空对象。只是纯好奇心,JS控制台中使用该变量发生了什么,如果您一次粘贴所有内容
在交互式控制台创造了一个人为的情况,在典型的代码执行中无法发生。
首先,您所看到的不是针对类构造函数丢弃的错误。如果您执行任何rhs引发错误的let
语句,则可以观察到相同的行为:
let myVariable = "".boom();
MDN上的文档讨论了一个"颞Zone",其中存在一个用let
声明的变量,但直到let
语句成功执行后才被视为不存在。
来自ES6规格:
变量是在实例化的词汇环境时创建的,但在评估变量的词汇互动之前,可能无法以任何方式访问。
简单地说,已创建了该变量,但无法访问,因为尚未评估其"词汇调节"。
使用控制台,您创建了一个情况:
-
let
语句尚未成功执行(因此,它是一个ReferenceError
尝试访问其变量)。 - 在同一范围内的相同变量名称中,您有两个
let
s(因此,第二个范围会产生语法错误)。(N.B.在同一范围中只有两个let
s会导致代码在 compilation阶段 ,如果您没有输入代码A,则第一个甚至有机会尝试执行代码。一次进入控制台)。
这种情况在普通代码中无法发生。
通常,您将无法继续在错误的范围内继续运行语句,因此第一个子弹是不可能的。该控制台允许您这样做。
在普通情况下,这将是不可能的,因为在第一个let
语句甚至可以尝试运行之前,代码将在汇编阶段失败。
这就是为什么在两种情况下都会遇到错误的原因。
好吧,这个问题实际上真的很有趣,而我 May 已经找到了答案。
您所描述的现象很可能与如何编译您的代码有关。虽然对程序员来说似乎是其他方面的,但汇编由几个步骤组成,并在此过程中在不同阶段执行。因此,根据您在代码中遇到的错误,此过程可以在该过程的任何时候终止。
因此,如果您的对象创建有缺陷(config
是未定义的),但是语法本身是可以的(从语言的角度来看),您将在汇编过程中与JavaScript中的某些非法的东西相比,您将在汇编过程中遇到错误。
参见,let
非常复杂,因为它可以防止可变命名碰撞(因此Indentifier 'myClassInstance' has already been defined
错误)。这与没有此功能的var
不同。
来自MDN文档:
在同一函数或块范围内重新启动相同的变量 提高语法。
if (x) { let foo; let foo; // SyntaxError thrown. }
在2015年的Ecmascript中,让将变量提升到顶部 堵塞。但是,在块中引用变量之前 可变声明会导致参考。该变量在 从街区开始到声明,"暂时死区" 已处理。
tl; dr
以下代码将在编译过程中较早触发错误
let myClassInstance = new MyClass();
let myClassInstance = '123';
与:
相比let myClassInstance = new MyClass();
myClassInstance = '123';
这是因为前者是JavaScript中的非法语法,而后者不是。在后一种情况下,代码会符合良好的良好,但由于参数不确定,因此在运行时会失败。
编辑:
我找到了这个博客,这是一个有趣的阅读。摘要:
嗯?简而言之,此JavaScript引擎将您的源代码拿到字符串中(又称为IT),将这些字符串分解为字符串,然后将它们转换为编译器可以理解的字节码,然后执行它。
。
这里的另一个深探教教程。