看书看迷糊了 求解答 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
victory
V2EX    Javascript

看书看迷糊了 求解答

  •  1
     
  •   victory 2022-04-06 17:08:48 +08:00 4241 次点击
    这是一个创建于 1291 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在看《 Javascript 高级程序设计(第 4 版)》第 3 章第 3 节变量 看迷糊了

    1. var 声明作用域 关键的问题在于,使用 var 操作符定义的变量会成为包含它的函数的局部变量。比如,使用 var 在一个函数内部定义一个变量,就意味着该变量将在函数退出时被销毁:
    function test() { var message = "hi"; // 局部变量 } test(); console.log(message); // 出错! } 

    下面这个代码为什么没有报错啊

    if (true) { var name = 'Matt'; console.log(name); // Matt } console.log(name); // Matt 

    这个 name 变量 怎么变成全局变量了

    31 条回复    2022-04-08 12:07:48 +08:00
    Puteulanus
        1
    Puteulanus  
       2022-04-06 17:10:49 +08:00   1
    “使用 var 操作符定义的变量会成为包含它的函数的局部变量”
    因为 if 的块不是函数呀
    kop1989smurf
        2
    kop1989smurf  
       2022-04-06 17:12:14 +08:00
    https://developer.mozilla.org/zh-CN/docs/Web/Javascript/Reference/Statements/var
    var 语句 用于声明一个函数范围或全局范围的变量,并可将其初始化为一个值(可选)。
    victory
        3
    victory  
    OP
       2022-04-06 17:14:39 +08:00
    @Puteulanus if()不是函数 if 的块不是函数 这两个是什么意思 我初学者没有编程经验 可以详细说一下吗
    noe132
        4
    noe132  
       2022-04-06 17:15:22 +08:00
    块作用域 !== 函数作用域。
    var 没有块作用域
    let/const 有块作用域

    { let myname = 'Matt'; console.log(myname); }
    console.log(myname); // Uncaught ReferenceError: myname is not defined

    另外 name 在浏览器中是个全局变量。
    einq7
        5
    einq7  
       2022-04-06 17:28:03 +08:00
    @victory #3 var 声明的变量没有块级作用域,if 的大括号和其所包含的是个语句块,所以在里面用 var 声明的变量,可以在语句块外部访问到
    victory
        6
    victory  
    OP
       2022-04-06 17:31:16 +08:00
    @einq7 感觉 Javascript 好多坑啊 有时候是局部变量,有时候是全局变量
    victory
        7
    victory  
    OP
       2022-04-06 17:32:43 +08:00
    还有一个问题 var 都是在什么情况下会变成全局变量
    stimw
        8
    stimw  
       2022-04-06 17:35:55 +08:00 via iPhone
    var 是老式的用法,有很多坑,现代 js 中应该避免使用 var 。var 是不受块( block )作用域限制的。block 本身也是现代 js 才引入的
    stimw
        9
    stimw  
       2022-04-06 17:37:08 +08:00
    这里讲的比较详细
    https://zh.Javascript.info/var
    shintendo
        10
    shintendo  
       2022-04-06 17:48:36 +08:00
    你为什么觉得,在你的例子里 name 是个全局变量
    nekochyan
        11
    nekochyan  
       2022-04-06 17:50:05 +08:00
    我怎么感觉你连什么是函数都没搞明白
    victory
        12
    victory  
    OP
       2022-04-06 17:56:51 +08:00
    @shintendo 可以在函数外使用的变量不叫全局变量叫什么
    shintendo
        13
    shintendo  
       2022-04-06 17:59:39 +08:00
    @victory 那么 name 在哪个函数外使用了?
    icebay
        14
    icebay  
       2022-04-06 18:24:40 +08:00
    Chell
        15
    Chell  
       2022-04-06 18:25:12 +08:00
    函数产生的是 function scope ,if 语句产生的是 block scope 。JS 没有实现 block scope ,但用 let 替代 var 可以产生你期待的效果。
    darkkylin
        16
    darkkylin  
       2022-04-06 18:36:27 +08:00
    楼主是不是受其他语言的影响了。建议看 ES6 的语法规则,按照新的规则来写。这种迷惑是历史原因了,语言设计导致,不用太纠结。
    ES6 以前 js 没有实现 block scope ,只有 function scope 和 global scope 。
    if 语句只是 block scope 。
    zhaol
        17
    zhaol  
       2022-04-06 18:36:44 +08:00
    if 不是函数啊
    xQmQ
        18
    xQmQ  
       2022-04-06 19:46:52 +08:00
    我主要是做后端搞 c++ 的,这几天刚学了一点 Javascript ,搞毕设的前端,也想问一下

    if (true) {
    var name = 'Matt';
    console.log(name); // Matt
    }
    console.log(name); // Matt

    name 为啥能用来打印呢? f() 判断式不能确定一定能进入(只是这里的恒定为 true ,保证了一定能进入),name 居然还定义成功了,我不能理解这种玩法
    Moeyua
        19
    Moeyua  
       2022-04-06 20:27:44 +08:00 via iPhone
    @xQmQ var 的变量声明会被提前到最开始,但此时不会被赋值,也就是如果 if 判断为 false ,这里打印的结果就会是 undefined
    xQmQ
        20
    xQmQ  
       2022-04-06 21:18:59 +08:00
    @Moeyua 试了一下,确实如此。但是之前先测试了 if(true) 的,输出两次;然后测试了 if(false) 的,也输出了两次。考虑了一下,应该是浏览器控制台记录了第一次时的值,导致第二次的 name 已经赋值了
    mascteen
        21
    mascteen  
       2022-04-06 21:22:39 +08:00 via Android
    换一本书看吧,这本书不符合新手,推荐权威指南
    jadehare
        22
    jadehare  
       2022-04-06 21:30:00 +08:00
    es6 建议使用 let 和 const ,不用管啥 var 啥作用域了,你叫一个开发很久习惯使用 let 的人来也得反应一会,这不是正常开发的思路。
    Leviathann
        23
    Leviathann  
       2022-04-06 23:00:45 +08:00
    es6 都快 10 年了
    demo06
        24
    demo06  
       2022-04-07 09:00:43 +08:00
    @xQmQ if 不是函数语句块,会导致变量作用域提升,所以你在 if(boolean){var xx=x;}所以你能打印成功
    demo06
        25
    demo06  
       2022-04-07 09:01:50 +08:00
    @xQmQ if 不是函数语句块,会导致变量作用域提升,所以你在 if(boolean){var xx=x;}时,var 变量会被提升到文件头部,所以你能打印成功
    demo06
        26
    demo06  
       2022-04-07 09:26:23 +08:00
    @xQmQ 不对我描述的有问题,应该是 Javascript 没有块级作用域,变量会被提升
    xQmQ
        27
    xQmQ  
       2022-04-07 09:55:24 +08:00
    @demo06 var 是没有块级作用域的,所以以下代码在浏览器控制台初次打印时提示 userName 是 undefined ,打印结果是 2.undefined ( userName 被提升了)

    if(false){
    var userName = 'test';
    console.log('1.'+userName);
    }
    console.log('2.'+userName);

    但是如果执行一次 if(true),再执行 if(false) 会打印成功;我这里猜测是因为解释器的原因,userName 被记录了,所以可以打印成功

    你提到『 Javascript 没有块级作用域』,var 没有,let 应该是有的
    demo06
        28
    demo06  
       2022-04-07 11:07:43 +08:00
    @xQmQ 在浏览器和 vs 里分别执行试了下,浏览器会记录,vs 还是 undefind
    xQmQ
        29
    xQmQ  
       2022-04-07 12:22:47 +08:00
    @demo06 浏览器估计是交互模式,带记录,vs 估计解释器直接执行文件了
    ljpCN
        30
    ljpCN  
       2022-04-07 14:31:50 +08:00
    关于块作用域楼上解释得差不多了,我给楼主一个建议:别用 var 。用 const 和 let 。
    dany813
        31
    dany813  
       2022-04-08 12:07:48 +08:00
    var 弃用吧,js 各种垃圾语法太多了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1402 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 16:54 PVG 00:54 LAX 09:54 JFK 12:54
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86