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
wunonglin 2021-02-14 02:10:20 +08:00
写得太骚了。
这题的关键是作用域吧?把 var 换成 let 就能得到 10 了,还有那两括号是什么意思还没找到,但是去掉括号一行行执行结果是 30 的,具体为什么我也不清楚,第一次见这样写,我悟了 |
4
lichdkimba 2021-02-14 02:19:23 +08:00 11
firefox 10 chrome 99
我服了 别出这种题目了行不行。。。。。。 |
5
Building 2021-02-14 02:28:11 +08:00 3
请问有什么需求要求一定要这样写吗?写个代码都搞得跟八股文似的。
|
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 1
```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 3
|
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 4
新时代八股
大清早就亡了 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
DOLLOR 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 2021-02-14 18:01:05 +08:00 via iPhone
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 4
好神奇! 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 了:
![image.png]( https://i.loli.net/2021/02/15/erJPX7dDu35RVq1.png) |
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 暂时的猜测是,非严格模式下的块儿内函数声明,会有提升覆盖,但运行到同名函数声明位置的时候,当前的同名变量的值会传递到全局 |