{
function a(){}
a=1
function a(){}
}
console.log(a,"1");
{
function a(){}
a=1
}
console.log(a,"2");
//输出
//1 '1'
//ƒ a(){} '2'
为啥第二个块的 a = 1 没有覆盖到全局的 a
1
murmur 2021-12-30 16:20:31 +08:00
function a(){} 1
function a(){} 2 这是 IE 的结果 所以出题人傻逼,完毕。 |
2
murmur 2021-12-30 16:21:36 +08:00
对了,刚才的结果也适用于 edge 浏览器,edge 够现代吧,不适用于 chrome
所以这不是出题人傻逼是什么 |
3
abear 2021-12-30 16:21:46 +08:00
先定义的不管,后定义的招殃
|
4
mxT52CRuqR6o5 2021-12-30 16:22:25 +08:00
|
5
vanton 2021-12-30 16:23:50 +08:00
这个题目不成立啦,不同环境不一样的。
|
6
mxT52CRuqR6o5 2021-12-30 16:28:42 +08:00
"use strict";
let a₀ = undefined; { let a₁ = function ( ){ }; a₁ = function ( ){ }; a₀ = a₁; a₁ = 1; a₀ = a₁; } console.log(a₀, "1"); { let a₁ = function ( ){ }; a₀ = a₁; a₁ = 1; } console.log(a₀, "2"); 大概就是这么个逻辑 也是因为非严格模式下块作用域有非常奇怪的难以理解的表现,所以搞了个严格模式出来 |
7
mxT52CRuqR6o5 2021-12-30 16:30:49 +08:00
es6 标准浏览器的非严格模式下运行这段代码是有一个固定确定的结果的,就是上面说的那个非常奇怪的难以理解的运行逻辑
|
8
iikebug 2021-12-30 16:33:24 +08:00
@mxT52CRuqR6o5 严格模式下,上面那段代码都跑不起来吧
|
9
libook 2021-12-30 16:33:50 +08:00 3
这个不是脑筋急转弯,这个是作用域提升,声明变量省略的 var 和 funciton 关键字都有作用域提升的特性。
第一个块的执行顺序实际上是先把两个 funciton 提到全局作用域,因为下面 console.log 输出 a ,所以稍后 a 也提到全局作用域,那么 a 的值变化就是先赋值为第一个 function ,再赋值为第二个 function ,最后赋值为 1 ,块下面 console.log 就输出 a 值为 1 。 第二个块里面,同样把 function 提到全局,后续因为此时全局已经有 a 了,后面的 console.log 能找到 a ,所以块内的 a 被认为是局部变量没有被提升作用域,所以块下面的 console.log 输出的是第二个块提升出去的 funciton a 。 换个写法可以帮助你理解这个顺序: { console.log(a(),"1"); function a(){return 2} a=1 function a(){return 3} } console.log(a,"4"); { function a(){return 5} a=2 console.log(a,"6"); } console.log(a(),"7"); |
10
mxT52CRuqR6o5 2021-12-30 16:34:56 +08:00
@iikebug 是的,会有 runtime error
|
11
EPr2hh6LADQWqRVH 2021-12-30 16:37:13 +08:00
我不知道,我只知道谁敢拿这个给我看我当场让他滚蛋
|
12
66beta 2021-12-30 16:39:33 +08:00
{
console.log(1, window.a, a); function a() {} console.log(2, window.a, a); a = 1; console.log(3, window.a, a); function a() {} console.log(4, window.a, a); } console.log('========', a, "1"); { console.log(5, window.a, a); function a() {} console.log(6, window.a, a); a = 1; console.log(7, window.a, a); } console.log('========', a, "2"); 1 、函数声明提升到块级顶部 2 、块内访问 a 是块内的,外面访问的是全局的 |
13
Biwood 2021-12-30 16:40:24 +08:00
脑筋急转弯可还行
|
15
iikebug 2021-12-30 16:44:30 +08:00
不能跑严格模式的都叫他滚。真就面试八股文?
|
16
murmur 2021-12-30 16:45:39 +08:00
@cheese edge 非 chrome 内核是我的结果,直接命令行打出来啊,要是别人出题有严格模式你跟我们说没严格模式,那是你的问题
|
17
cheese OP @mxT52CRuqR6o5 #6 我自己的推测也是类似这个逻辑,但是我没法理解为什么。第二个块到 a₁ = 1;就停止了,而没有 a₀ = a₁; 这个步骤
|
18
churchill 2021-12-30 16:54:03 +08:00 1
https://tc39.es/ecma262/#sec-block-level-function-declarations-web-legacy-compatibility-semantics
> Prior to ECMAScript 2015, the ECMAScript specification did not define the occurrence of a FunctionDeclaration as an element of a Block statement's StatementList. However, support for that form of FunctionDeclaration was an allowable extension and most browser-hosted ECMAScript implementations permitted them. Unfortunately, the semantics of such declarations differ among those implementations. |
19
churchill 2021-12-30 16:54:59 +08:00
js 版的 ub 而已,:)
|
20
mxT52CRuqR6o5 2021-12-30 16:58:40 +08:00
|
21
murmur 2021-12-30 16:59:44 +08:00
你们吐槽谭浩强的勇气呢,怎么现在开始讨论这种恶心人的东西呢,生产写这种东西有几次你被打死几次
|
22
mxT52CRuqR6o5 2021-12-30 17:04:50 +08:00 1
|
23
cheese OP @mxT52CRuqR6o5 #22 好的,感谢
|
24
liubaicai 2021-12-30 17:17:47 +08:00
有什么意义啊,谁生产会写这种代码?面试出这种题的也是 zz 。
|
25
iwasthere 2021-12-30 21:20:34 +08:00 via iPhone
因为如果变量名称跟已经声明的函数相同,则变量声明不会干扰已经存在的这类属性。
|
26
enchilada2020 2021-12-30 23:03:53 +08:00 via Android
我承认我不会 JS
|
27
litel 2021-12-31 11:16:33 +08:00
大家好像都没解释题主的“第二个块的 a=1 为什么没有提升至全局”
我也搞不清楚这里…… |
28
litel 2021-12-31 11:29:23 +08:00
@mxT52CRuqR6o5 那为什么第二个块的 a = 1 不会抛出到全局作用域呢?
就算是 b = 1 { b = 2 } b // => 2 块作用域的 b 也会到全局,为什么最后不加同名 funtion 就不会到全局呢? 这里比较疑惑 |
29
mxT52CRuqR6o5 2021-12-31 11:34:27 +08:00
|
30
mxT52CRuqR6o5 2021-12-31 11:40:48 +08:00
@litel
你所说的东西我尝试解释一下(一下内容为马后炮,根据结果猜测运行原理) es6 非严格模式在块内声明 function 会同时在全局和块内生命同名变量,所以在块内对同名变量赋值只会影响块内 而 b = 1 { b = 2 } 只有全局的 b ,没有块内的 b ,块内的赋值语句就直接修改了全局的 b |
31
wangtian2020 2021-12-31 14:10:37 +08:00
有 globalThis 我就是不用
欸我就是玩儿 |
32
wangtian2020 2021-12-31 14:12:27 +08:00
|
33
qeqv 2022-01-01 11:18:35 +08:00
@wangtian2020 学了这个会不会被同事打死
|