在看《 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 1
“使用 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 各种垃圾语法太多了
|