推荐关注
› Meteor
› JSLint - a JavaScript code quality tool
› jsFiddle
› D3.js
› WebStorm
推荐书目
› JavaScript 权威指南第 5 版
› Closure: The Definitive Guide
MLLB

询问一个 JS 函数题

  •  1
     
  •   MLLB · Feb 14, 2021 · 6014 views
    This topic created in 2089 days ago, the information mentioned may be changed or developed.
    var a = 10; {
        a = 99;
    
        function a() {
            console.log(a);
        }
        a = 30;
    }
    console.log(a);
    

    如上,请问为什么最终的打印结果是 99 呢?

    Supplement 1  ·  Feb 14, 2021
    各位,我也实属无奈。这是学校出的题目,老师说得也是似懂非懂,就来问各位大佬了。
    37 replies  •  2021-02-19 16:09:27 +08:00
    xy90321
    xy90321
    Feb 14, 2021
    1
    变量作用域往上找,找到啥就是啥。
    另外你什么浏览器跑的是 99 ?
    dousha99
    dousha99
    Feb 14, 2021
    2
    @xy90321 在 NodeJS 15.8.0 的 REPL 里测试,确实输出 99. Firefox 85 下测试结果为 10.

    我原以为 JS 里没有这种未定义行为 /依赖于解释器实现的行为,今天是长见识了。
    shakaraka
    shakaraka
    Feb 14, 2021
    3
    写得太骚了。

    这题的关键是作用域吧?把 var 换成 let 就能得到 10 了,还有那两括号是什么意思还没找到,但是去掉括号一行行执行结果是 30 的,具体为什么我也不清楚,第一次见这样写,我悟了
    lichdkimba
    lichdkimba
    Feb 14, 2021❤️11
    4
    firefox 10 chrome 99

    我服了 别出这种题目了行不行。。。。。。
    Building
    Building
    Feb 14, 2021❤️3
    5
    请问有什么需求要求一定要这样写吗?写个代码都搞得跟八股文似的。
    Caballarii
    Caballarii
    Feb 14, 2021
    6
    js 是世界上最好的语言
    POPOEVER
    POPOEVER
    Feb 14, 2021
    7
    {} 的写法相当于 var
    kaiki
    kaiki
    Feb 14, 2021
    8
    自从我知道不同浏览器的 JS 代码有不同的支持的时候,就不会去写这种花里胡哨的代码了。
    能跑出一样的结果就行,反正是在客户的机子上跑,又不占我服务器,效率低点就低点。
    mrochcnnnnn
    mrochcnnnnn
    Feb 14, 2021 via iPhone
    9
    @Caballarii 😂😂😂😂论坛气氛组就位,Java 不服
    iugo
    iugo
    Feb 14, 2021❤️1
    10
    ```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 下, 基本是写不出这么 "错误的" 代码的. 肯定会在写的时候报错.
    across
    across
    Feb 14, 2021 via iPhone
    11
    看结果明白为什么(同名函数区域覆盖)。
    不过具体规则懒得找了,现在都用 let 而且搞同名写法也会被骂的...
    finalwave
    finalwave
    Feb 14, 2021
    13
    Sample
    Sample
    Feb 14, 2021❤️4
    14
    新时代八股
    大清早就亡了
    es2020 都来了
    let 也可以考察作用域
    该公司的代码难道也这样写吗?
    茴香豆的茴字就贵公司知道有四种写法?

    非要拿着旧时代的裹脚布狂舔,真的不恶心吗
    f0rger
    f0rger
    Feb 14, 2021 via iPhone
    15
    第一眼也是应该不是 99
    我逆向推,得到 across 的答案。
    不过这写法真的是吐了……
    crab
    crab
    Feb 14, 2021
    16
    @lichdkimba C 中的 多次++ -- 😭
    AV1
    AV1
    Feb 14, 2021
    17
    尽量用函数表达式 const func = ()=>{...},而不是函数声明 function func(){...}
    rodrick
    rodrick
    Feb 14, 2021
    18
    别搞这种题了。。真的累
    MLLB
    MLLB
    OP
    Feb 14, 2021
    19
    @lichdkimba 我也实属无奈。要做。
    MLLB
    MLLB
    OP
    Feb 14, 2021
    20
    @Building 可以理解为学校的题目。
    across
    across
    Feb 14, 2021 via iPhone
    21
    这种题目拿来做分析理解其实没什么问题,可以认识到 js 的缺陷表现。
    你不知道的 js 第一本有专区讲过这些问题
    zhoudaiyu
    zhoudaiyu
    Feb 14, 2021 via iPhone
    22
    int a = 5; a= ++++++a++++++++; cout << a;
    cyberpoint
    cyberpoint
    Feb 14, 2021
    23
    现在出这种题目的都是 NT
    ttoott200
    ttoott200
    Feb 14, 2021❤️4
    24
    好神奇! a = 99 改变了全局变量 a,函数声明 function a() 相当于以 let 方式创建了一个局部变量 a,后面的 a = 30 改变了局部变量,不会影响到全局变量,最后输出的 a 是 99 。
    Kininaru
    Kininaru
    Feb 14, 2021 via Android
    25
    如果我同事写这种代码给我看,我会考虑偷偷拔掉他的头发
    AndyAO
    AndyAO
    Feb 14, 2021
    26
    学校里居然开始教 JavaScript 了 !

    请问楼主你是什么学校?什么专业?
    autoxbc
    autoxbc
    Feb 14, 2021
    27
    @Caballarii #6 JavaScript 天天抄别人的语言特性,早晚会抄成最好的语言
    deepall
    deepall
    Feb 14, 2021
    28
    safari 30
    chrome 99
    哈哈哈
    justin2018
    justin2018
    Feb 14, 2021
    29
    我这有的学校外聘老师讲课 讲一次课 1k 左右

    一个月 几节课~
    wish8023
    wish8023
    Feb 14, 2021
    30
    wish8023
    wish8023
    Feb 14, 2021
    31
    @wish8023
    额,自己看调用栈吧!
    https://sm.ms/image/JZmKwI8Pgu3pWBD
    wish8023
    wish8023
    Feb 14, 2021
    32
    调用栈:
    jinliming2
    jinliming2
    Feb 15, 2021
    33
    IE 下、旧 IE 下打印的是 function a() { console.log(a); }:
    https://i.loli.net/2021/02/15/S97y1WPJxCRlAj2.png
    jinliming2
    jinliming2
    Feb 15, 2021
    34
    但是添加 "use strict" 之后就打印 10 了:
    ![image.png]( https://i.loli.net/2021/02/15/erJPX7dDu35RVq1.png)
    mxT52CRuqR6o5
    mxT52CRuqR6o5
    Feb 15, 2021
    35
    现在上学没办法,毕业之后不要太研究这种东西,不然就成孔乙己了
    lixingjun
    lixingjun
    Feb 15, 2021
    36
    实战中这种问题几乎碰不到,还是多实现一些确定的功能,代码水平才能真正进步
    Roger006
    Roger006
    Feb 19, 2021
    37
    和朋友讨论调试后,对非严格模式下的结果有个猜测。修改原有代码为以下。都是在桌面 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

    暂时的猜测是,非严格模式下的块儿内函数声明,会有提升覆盖,但运行到同名函数声明位置的时候,当前的同名变量的值会传递到全局
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   2867 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 66ms · UTC 10:55 · PVG 18:55 · LAX 02:55 · JFK 05:55
    ♥ Do have faith in what you're doing.