var a = 10; { a = 99; function a() { console.log(a); } a = 30; } console.log(a);
如上,请问为什么最终的打印结果是 99 呢?
1 xy90321 2021-02-14 01:11:17 +08:00 变量作用域往上找,找到啥就是啥。 另外你什么浏览器跑的是 99 ? |
2 dousha99 2021-02-14 01:40:24 +08:00 @xy90321 在 NodeJS 15.8.0 的 REPL 里测试,确实输出 99. Firefox 85 下测试结果为 10. 我原以为 JS 里没有这种未定义行为 /依赖于解释器实现的行为,今天是长见识了。 |
![]() | 3 shakaraka PRO 写得太骚了。 这题的关键是作用域吧?把 var 换成 let 就能得到 10 了,还有那两括号是什么意思还没找到,但是去掉括号一行行执行结果是 30 的,具体为什么我也不清楚,第一次见这样写,我悟了 |
![]() | 4 lichdkimba 2021-02-14 02:19:23 +08:00 ![]() firefox 10 chrome 99 我服了 别出这种题目了行不行。。。。。。 |
![]() | 5 Building 2021-02-14 02:28:11 +08:00 ![]() 请问有什么需求要求一定要这样写吗?写个代码都搞得跟八股文似的。 |
6 Caballarii 2021-02-14 02:38:28 +08:00 js 是世界上最好的语言 |
![]() | 7 POPOEVER 2021-02-14 03:02:15 +08:00 {} 的写法相当于 var |
![]() | 8 kaiki 2021-02-14 03:11:34 +08:00 自从我知道不同浏览器的 JS 代码有不同的支持的时候,就不会去写这种花里胡哨的代码了。 能跑出一样的结果就行,反正是在客户的机子上跑,又不占我服务器,效率低点就低点。 |
![]() | 9 mrochcnnnnn 2021-02-14 03:29:19 +08:00 via iPhone @Caballarii 论坛气氛组就位,Java 不服 |
![]() | 10 iugo 2021-02-14 09:31:09 +08:00 ![]() ```js var a = 10; for (let i = 0; i < 1; i++) { a = 99; function a() { console.log(a); } a = 30; } console.log(a); ``` 这样看我们就容易接受一点. 我预期应该是返回 10 的, 之所以返回 99 可能和 V8 在作用域内没有函数声明进行提升有关. 刚好, 我们要强调, 在写 JS 的时候有如下要注意: 1. 在函数声明时, 避免重名. 2. 函数声明时, 尽量在顶级, 否则使用箭头函数. 在 ESLint 下或者 TypeScript 下, 基本是写不出这么 "错误的" 代码的. 肯定会在写的时候报错. |
11 across 2021-02-14 10:03:34 +08:00 via iPhone 看结果明白为什么(同名函数区域覆盖)。 不过具体规则懒得找了,现在都用 let 而且搞同名写法也会被骂的... |
![]() | 12 oott123 2021-02-14 11:14:36 +08:00 via Android ![]() |
![]() | 13 finalwave 2021-02-14 11:38:27 +08:00 https://developer.mozilla.org/zh-CN/docs/Web/Javascript/Reference/Functions#%E5%9D%97%E7%BA%A7%E5%87%BD%E6%95%B0 非严格模式下的块级函数问题。 if 和 for 里面的实现取决于浏览器,参考 https://developer.mozilla.org/zh-CN/docs/Web/Javascript/Reference/Statements/function#%E6%9C%89%E6%9D%A1%E4%BB%B6%E7%9A%84%E5%88%9B%E5%BB%BA%E5%87%BD%E6%95%B0 总的来说就像 10 楼说的,别这么用,要用就上匿名函数。 |
14 Sample 2021-02-14 11:59:05 +08:00 ![]() 新时代八股 大清早就亡了 es2020 都来了 let 也可以考察作用域 该公司的代码难道也这样写吗? 茴香豆的茴字就贵公司知道有四种写法? 非要拿着旧时代的裹脚布狂舔,真的不恶心吗 |
![]() | 15 f0rger 2021-02-14 13:04:49 +08:00 via iPhone 第一眼也是应该不是 99 我逆向推,得到 across 的答案。 不过这写法真的是吐了…… |
![]() | 16 crab 2021-02-14 13:37:55 +08:00 @lichdkimba C 中的 多次++ -- |
![]() | 17 AV1 2021-02-14 16:53:04 +08:00 尽量用函数表达式 const func = ()=>{...},而不是函数声明 function func(){...} |
![]() | 18 rodrick 2021-02-14 17:04:36 +08:00 别搞这种题了。。真的累 |
![]() | 19 MLLB OP @lichdkimba 我也实属无奈。要做。 |
21 across 2021-02-14 17:55:16 +08:00 via iPhone 这种题目拿来做分析理解其实没什么问题,可以认识到 js 的缺陷表现。 你不知道的 js 第一本有专区讲过这些问题 |
![]() | 22 zhoudaiyu PRO int a = 5; a= ++++++a++++++++; cout << a; |
23 cyberpoint 2021-02-14 18:01:35 +08:00 现在出这种题目的都是 NT |
24 ttoott200 2021-02-14 18:28:49 +08:00 ![]() 好神奇! a = 99 改变了全局变量 a,函数声明 function a() 相当于以 let 方式创建了一个局部变量 a,后面的 a = 30 改变了局部变量,不会影响到全局变量,最后输出的 a 是 99 。 |
![]() | 25 Kininaru 2021-02-14 18:45:18 +08:00 via Android 如果我同事写这种代码给我看,我会考虑偷偷拔掉他的头发 |
![]() | 26 AndyAO 2021-02-14 18:46:58 +08:00 学校里居然开始教 Javascript 了 ! 请问楼主你是什么学校?什么专业? |
![]() | 27 autoxbc 2021-02-14 19:04:44 +08:00 @Caballarii #6 Javascript 天天抄别人的语言特性,早晚会抄成最好的语言 |
![]() | 28 deepall 2021-02-14 20:06:25 +08:00 safari 30 chrome 99 哈哈哈 |
![]() | 29 justin2018 2021-02-14 20:29:45 +08:00 我这有的学校外聘老师讲课 讲一次课 1k 左右 一个月 几节课~ |
![]() | 30 wish8023 2021-02-14 20:39:21 +08:00 |
![]() | 31 wish8023 2021-02-14 20:44:47 +08:00 |
![]() | 32 wish8023 2021-02-14 20:47:33 +08:00 |
33 jinliming2 2021-02-15 00:25:34 +08:00 IE 下、旧 IE 下打印的是 function a() { console.log(a); }: https://i.loli.net/2021/02/15/S97y1WPJxCRlAj2.png |
34 jinliming2 2021-02-15 00:28:29 +08:00 但是添加 "use strict" 之后就打印 10 了:  |
35 mxT52CRuqR6o5 2021-02-15 00:38:07 +08:00 现在上学没办法,毕业之后不要太研究这种东西,不然就成孔乙己了 |
![]() | 36 lixingjun 2021-02-15 10:36:59 +08:00 实战中这种问题几乎碰不到,还是多实现一些确定的功能,代码水平才能真正进步 |
37 Roger006 2021-02-19 16:09:27 +08:00 和朋友讨论调试后,对非严格模式下的结果有个猜测。修改原有代码为以下。都是在桌面 chrome v88 测试出来的情况。 0. 1. var a = 10; { 2. console.log(a); 3. a = 99; 4. function a(x) {} 5. a = 12; 6. function a() {} 7. a = 30; 8. console.log(a); } 9.console.log(a); 代码运行到 [打断点地方] 0 位置,global=>a//undefined 1 位置 global => a//undefined 2 位置 g=>a//10 block=>a// function a(){} 3 位置 g=>a//10 block=>a// function a(){} 4 位置 g=>a//10 block=a//99 5 位置 g=>a//99 b=>a//99 6 位置 g=>a//99 b=>a//12 7 位置 g=>a//12 b=>a//12 8 位置 g=>a//12 b=>a//30 9 位置 g=>a//12 暂时的猜测是,非严格模式下的块儿内函数声明,会有提升覆盖,但运行到同名函数声明位置的时候,当前的同名变量的值会传递到全局 |