在看《 Javascript 高级程序设计(第 4 版)》第 3 章第 3 节变量 看迷糊了
function test() { var message = "hi"; // 局部变量 } test(); console.log(message); // 出错! }
下面这个代码为什么没有报错啊
if (true) { var name = 'Matt'; console.log(name); // Matt } console.log(name); // Matt
这个 name 变量 怎么变成全局变量了
![]() | 1 Puteulanus 2022-04-06 17:10:49 +08:00 ![]() “使用 var 操作符定义的变量会成为包含它的函数的局部变量” 因为 if 的块不是函数呀 |
![]() | 2 kop1989smurf 2022-04-06 17:12:14 +08:00 https://developer.mozilla.org/zh-CN/docs/Web/Javascript/Reference/Statements/var var 语句 用于声明一个函数范围或全局范围的变量,并可将其初始化为一个值(可选)。 |
![]() | 3 victory OP @Puteulanus if()不是函数 if 的块不是函数 这两个是什么意思 我初学者没有编程经验 可以详细说一下吗 |
![]() | 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 在浏览器中是个全局变量。 |
5 einq7 2022-04-06 17:28:03 +08:00 @victory #3 var 声明的变量没有块级作用域,if 的大括号和其所包含的是个语句块,所以在里面用 var 声明的变量,可以在语句块外部访问到 |
![]() | 7 victory OP 还有一个问题 var 都是在什么情况下会变成全局变量 |
![]() | 8 stimw 2022-04-06 17:35:55 +08:00 via iPhone var 是老式的用法,有很多坑,现代 js 中应该避免使用 var 。var 是不受块( block )作用域限制的。block 本身也是现代 js 才引入的 |
![]() | 9 stimw 2022-04-06 17:37:08 +08:00 这里讲的比较详细 https://zh.Javascript.info/var |
![]() | 10 shintendo 2022-04-06 17:48:36 +08:00 你为什么觉得,在你的例子里 name 是个全局变量 |
![]() | 11 nekochyan 2022-04-06 17:50:05 +08:00 我怎么感觉你连什么是函数都没搞明白 |
14 icebay 2022-04-06 18:24:40 +08:00 |
![]() | 15 Chell 2022-04-06 18:25:12 +08:00 函数产生的是 function scope ,if 语句产生的是 block scope 。JS 没有实现 block scope ,但用 let 替代 var 可以产生你期待的效果。 |
![]() | 16 darkkylin 2022-04-06 18:36:27 +08:00 楼主是不是受其他语言的影响了。建议看 ES6 的语法规则,按照新的规则来写。这种迷惑是历史原因了,语言设计导致,不用太纠结。 ES6 以前 js 没有实现 block scope ,只有 function scope 和 global scope 。 if 语句只是 block scope 。 |
![]() | 17 zhaol 2022-04-06 18:36:44 +08:00 if 不是函数啊 |
![]() | 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 居然还定义成功了,我不能理解这种玩法 |
![]() | 19 Moeyua 2022-04-06 20:27:44 +08:00 via iPhone @xQmQ var 的变量声明会被提前到最开始,但此时不会被赋值,也就是如果 if 判断为 false ,这里打印的结果就会是 undefined |
![]() | 20 xQmQ 2022-04-06 21:18:59 +08:00 @Moeyua 试了一下,确实如此。但是之前先测试了 if(true) 的,输出两次;然后测试了 if(false) 的,也输出了两次。考虑了一下,应该是浏览器控制台记录了第一次时的值,导致第二次的 name 已经赋值了 |
![]() | 21 mascteen 2022-04-06 21:22:39 +08:00 via Android 换一本书看吧,这本书不符合新手,推荐权威指南 |
22 jadehare 2022-04-06 21:30:00 +08:00 es6 建议使用 let 和 const ,不用管啥 var 啥作用域了,你叫一个开发很久习惯使用 let 的人来也得反应一会,这不是正常开发的思路。 |
23 Leviathann 2022-04-06 23:00:45 +08:00 es6 都快 10 年了 |
![]() | 24 demo06 2022-04-07 09:00:43 +08:00 @xQmQ if 不是函数语句块,会导致变量作用域提升,所以你在 if(boolean){var xx=x;}所以你能打印成功 |
![]() | 25 demo06 2022-04-07 09:01:50 +08:00 @xQmQ if 不是函数语句块,会导致变量作用域提升,所以你在 if(boolean){var xx=x;}时,var 变量会被提升到文件头部,所以你能打印成功 |
![]() | 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 应该是有的 |
30 ljpCN 2022-04-07 14:31:50 +08:00 关于块作用域楼上解释得差不多了,我给楼主一个建议:别用 var 。用 const 和 let 。 |
![]() | 31 dany813 2022-04-08 12:07:48 +08:00 var 弃用吧,js 各种垃圾语法太多了 |