-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JavaScript-TDZ与变量提升 #1
Comments
Vue methods 中的变量提升问题
在Vue的methods中和一个普通的js中执行如下代码会得到不同的结果; 在Vue的methods中: test() {
console.log(a); // undefine (竟然没有报错)
let a = 1;
} 在普通的js文件中: test() {
console.log(a); // Uncaught ReferenceError: a is not defined(报错了)
let a = 1;
} 对比,我们可能会觉得在Vue的methods中用let和Vue声明的变量是存在变量提升的,但是提升到哪里我们得继续探讨,在Vue的methods中继续执行如下的方法: test() {
console.log(a); // Uncaught ReferenceError: a is not defined(报错了)
if(true) {
let a = 1;
}
} 我们可以发现此时代码报错了,说明就算存在变量提升,至少也不是提升到函数作用域,我们继续执行下面的代码: test() {
if(true) {
console.log(a); // undefined(没有报错)
let a = 1;
}
} 发现没有,没有报错,这可能会使我们更坚定的认为在Vue的methods中用let和const声明变量是存在变量提升的,但不是提升到函数作用域,那是提升到变量所在的块级作用域?在下最后的结论之前,我们分别在普通的JS和Vue的methods方法中分别执行如下代码。 test(value) {
if (value === 1) {
let a = 1;
} else if(value === 2) {
let a = 2;
} else if (value === 3) {
let a = 3;
} else {
let a = 4;
}
} 上图是执行的Vue的实例方法,下图是在普通的JS中执行的同样的方法,我们把关注点放在作用域部分。可以看中普通的JS中a(仅有一个a)是放在Block作用域中的。而在Vue的实例方法中,a是放在Local作用域中的,并且创建了三个临时变量(在这里姑且先称作临时变量吧)_a、_a2、_a3,并且当代码执行到断点处时,_a3的值为4,而a的值却为undefined,但是当我们试图在变量a所在的作用域访问这些临时变量时我们发现代码报错了,入下: // test()
test(value) {
if (value === 1) {
let a = 1;
} else if(value === 2) {
let a = 2;
} else if (value === 3) {
let a = 3;
} else {
console.log(a);
console.log(_a3); // ReferenceError: _a3 is not defined
console.log(_a);
console.log(_a3);
let a = 4;
console.log(a);
debugger;
}
} 那我们就会想Vue中的实例方法为啥有着和普通JS中如此不同的表现?为啥要创造这些临时变量呢?为啥Vue的methods中的方法用let声明的变量竟然没有块级作用域呢?竟然是放在局部作用域Local中的,这与我们之前的认知有很大的不同,我们前面的那些猜测是对的吗? 带着这些疑问,我们继续往下探索,最后终于发现问题的源头竟然出在Babel,因为我们这里的代码其实是经过Babel编译的,Babel会把如下图中左侧的代码编译成下面的这样。 这样就能解释清楚为啥Vue中let声明的变量的作用域是在函数的局部作用域Local中,变量_a、_a2、_a3也就顺理成章的解释清楚了。上面说的在Vue中执行的方法,只要在Babel中编译一下你就能理解它们不正常的行为其实是没有问题的,因为Balel编译了它们。 总结总结一下: |
JavaScript-TDZ & 一次混淆
let会不会把变量提升
The difference between var/function/function* declarations and let/const/class declarations is the initialisation.
MDN let文档
TDZ 临时死区
The text was updated successfully, but these errors were encountered: