You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
个人猜测,可能 a = 21 这里的 a 依然是那个特殊作用域内的 a 变量(即原先指向函数的),此时赋值改变没有问题,但是其重新赋值不会重新映射到全局环境了,这里的 a 与全局环境的 a 是两个不同环境的变量,只不过中间有个 function a() {} 曾经将它们两的值映射为同一个,可能通过下面代码说明更好理解:
vara1='a1'vara2=a1a2='aa'a1// a1
即上述代码,其实全局环境的 a 与含有 function a() {} 的 if 条件内的 a 应该算是两个变量,但是引擎会把 function a() {} 之前的关于 a 变量的代码映射到全局环境上,但是之后的不会。可以看下面代码:
if(true){functionb(){};b=1;console.log('inside',b);// 1}console.log('outside',b);// function
这种代码主要了解即可,工作中不要用!
The text was updated successfully, but these errors were encountered:
关于函数块级作用域基础的一道题
今天看到高级前端进阶推送的一篇文章,关于js基础的,我答错了,但是看了他的讲解,并没有让我理解这个问题,所以我自己记录并理解下。
看到这题,我下意识地认为全都输出 21,但错了,错在 全局环境下的打印输出!
有点经验的前端应该都知道,函数声明存在变量提升。所以上述代码第4种变型就很好理解,虽然函数声明在第四行才写出来,但是js引擎执行时会将其声明提升并覆盖第一行的
var a
。而第3种变型区别在于赋值,所以js引擎声明变量并赋值本质顺序是下面这样的:即
var a = 0
被拆开成先声明a
,等变量提升声明完成后才会进行赋值,到这一步应该很好理解。再看第1种和第2种变型,其实就是对全局变量a
的赋值与打印罢了。由于这里是全局作用域下的代码,结合 GlobalDeclarationInstantiation ( script, env ) 可知,var
与function
声明的变量会成为全局对象的属性,而赋值运算看 重学js —— 赋值运算符 就能理解。接下来继续看变型代码:
为什么?这里看MDN的解释:非严格模式下的块级函数,MDN直接坦言:不要用! 当然,在日常工作中我几乎没这么用过,但是不用不代表不需要懂。也见:有条件的创建函数
这又是什么情况呢?不是说好的函数声明变量提升吗?那第一个输出的
window.a
为何是 0 而不是function a(){}
呢???其实这个继续看 有条件的创建函数 就能理解了,把MDN的示例稍微改下:回顾上述代码,大致可以看出,虽然
if
判断内函数声明提升了,但是只有在函数代码后的打印输出才会影响到全局对象,这里跟全局环境下不同。继续看代码变型:这里就很奇怪了!疑惑点在于
a = 1
后立即打印window.a
没变,而函数后的打印却改变了!!!难道这里
a = 1
的a
,指的是function a() {}
这个函数名引用,而不是全局环境var a
的引用???是不是意味着这里先有个保存函数的作用域,此时函数声明提升,函数名
a
保存在该作用域内,而函数之前的代码a = 1
也在该作用域内,只是对保存函数引用的变量a
进行赋值更改?然后当真正执行到函数代码后,再把该作用域内的a
变量映射到全局环境,覆盖原先的值?那原题在函数后面的
a = 21
如何解释呢?个人猜测,可能
a = 21
这里的a
依然是那个特殊作用域内的a
变量(即原先指向函数的),此时赋值改变没有问题,但是其重新赋值不会重新映射到全局环境了,这里的a
与全局环境的a
是两个不同环境的变量,只不过中间有个function a() {}
曾经将它们两的值映射为同一个,可能通过下面代码说明更好理解:即上述代码,其实全局环境的
a
与含有function a() {}
的if
条件内的a
应该算是两个变量,但是引擎会把function a() {}
之前的关于a
变量的代码映射到全局环境上,但是之后的不会。可以看下面代码:这种代码主要了解即可,工作中不要用!
The text was updated successfully, but these errors were encountered: