当前位置: 首页 > 科技观察

来自一个关于“范围”和“晋升”的奇怪的JS面试问题

时间:2023-03-23 11:35:57 科技观察

“面试造火箭,工作拧螺丝”。面试问题的怪异往往令人难以置信。试试一道关于“提升”的面试题:1.提升全局变量varvartmp=newDate();functionf(){console.log(tmp);if(false){vartmp="hello";}}f();JS新手往往以为日期会正常打印出来,但实际输出的是`undefined`!>vartmp=newDate();>functionf(){...console.log(tmp);...if(false){.....vartmp="hello";...}...}>f();undefined这是因为在函数f()内部,var被提升到域的顶部,实际执行是:vartmp=newDate();functionf(){vartmp;//这里提升了,全局的tmp覆盖。var的默认赋值是undefinedconsole.log(tmp);if(false){vartmp="hello";}}f();也就是说var不仅被提升了,还把tmp初始化为undefined。2.如何正常输入日期?解决方案是将全局作用域的var替换为块作用域的let:vartmp=newDate();functionf(){//vartmp;//提升到这里,全局tmp被覆盖。var默认赋值是undefinedconsole.log(tmp);if(false){lettmp="hello";}}f();//2021-04-02T10:52:30.983Z这是因为let定义了local-variable.3.TDZTemporaryDeadZones是更奇怪的情况,让我们分开来看:vartmp=newDate();functionf(){console.log(tmp);lettmp="hello";}f();你以为会像往常一样把时间打印出来,结果报错tmpisnotdefined。ReferenceError:Cannotaccess'tmp'beforeinitialization这是因为tmp被提升了,它的实际执行是:vartmp=newDate();functionf(){lettmp;//这里提升console.log(tmp);lettmp="hello";}F();但是和var不同的是,tmp只是被提升了,不会自动赋值给undefined,所以会报ReferenceError。这个问题就是传说中的TDZ(temporaldeadzone)。解决方法也很简单,就是把let或者const都写到最上面。