V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Sponsored by
LinkedIn
不坐班的神仙工作 · 去任何你想去的地方远程,赚一线城市的工资
2000 个不用出门 Social 的全球远程工作,帮助 V2EX 的小伙伴开启全新的工作方式。
Promoted by LinkedIn
victory
V2EX  ›  JavaScript

看书看迷糊了 求解答

  •  1
     
  •   victory · 175 天前 · 2858 次点击
    这是一个创建于 175 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在看《 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  
       175 天前   ❤️ 1
    “使用 var 操作符定义的变量会成为包含它的函数的局部变量”
    因为 if 的块不是函数呀
    kop1989smurf
        2
    kop1989smurf  
       175 天前
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/var
    var 语句 用于声明一个函数范围或全局范围的变量,并可将其初始化为一个值(可选)。
    victory
        3
    victory  
    OP
       175 天前
    @Puteulanus if()不是函数 if 的块不是函数 这两个是什么意思 我初学者没有编程经验 可以详细说一下吗
    noe132
        4
    noe132  
       175 天前
    块作用域 !== 函数作用域。
    var 没有块作用域
    let/const 有块作用域

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

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

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

    name 为啥能用来打印呢? f() 判断式不能确定一定能进入(只是这里的恒定为 true ,保证了一定能进入),name 居然还定义成功了,我不能理解这种玩法
    Moeyua
        19
    Moeyua  
       174 天前 via iPhone
    @xQmQ var 的变量声明会被提前到最开始,但此时不会被赋值,也就是如果 if 判断为 false ,这里打印的结果就会是 undefined
    xQmQ
        20
    xQmQ  
       174 天前
    @Moeyua 试了一下,确实如此。但是之前先测试了 if(true) 的,输出两次;然后测试了 if(false) 的,也输出了两次。考虑了一下,应该是浏览器控制台记录了第一次时的值,导致第二次的 name 已经赋值了
    mascteen
        21
    mascteen  
       174 天前 via Android
    换一本书看吧,这本书不符合新手,推荐权威指南
    jadehare
        22
    jadehare  
       174 天前
    es6 建议使用 let 和 const ,不用管啥 var 啥作用域了,你叫一个开发很久习惯使用 let 的人来也得反应一会,这不是正常开发的思路。
    Leviathann
        23
    Leviathann  
       174 天前
    es6 都快 10 年了
    demo06
        24
    demo06  
       174 天前
    @xQmQ if 不是函数语句块,会导致变量作用域提升,所以你在 if(boolean){var xx=x;}所以你能打印成功
    demo06
        25
    demo06  
       174 天前
    @xQmQ if 不是函数语句块,会导致变量作用域提升,所以你在 if(boolean){var xx=x;}时,var 变量会被提升到文件头部,所以你能打印成功
    demo06
        26
    demo06  
       174 天前
    @xQmQ 不对我描述的有问题,应该是 javascript 没有块级作用域,变量会被提升
    xQmQ
        27
    xQmQ  
       174 天前
    @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  
       174 天前
    @xQmQ 在浏览器和 vs 里分别执行试了下,浏览器会记录,vs 还是 undefind
    xQmQ
        29
    xQmQ  
       174 天前
    @demo06 浏览器估计是交互模式,带记录,vs 估计解释器直接执行文件了
    ljpCN
        30
    ljpCN  
       174 天前
    关于块作用域楼上解释得差不多了,我给楼主一个建议:别用 var 。用 const 和 let 。
    dany813
        31
    dany813  
       173 天前
    var 弃用吧,js 各种垃圾语法太多了
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4326 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 09:33 · PVG 17:33 · LAX 02:33 · JFK 05:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.