【发布时间】:2021-04-25 09:58:27
【问题描述】:
我正在对范围进行一些试验,但偶然发现了这个我不明白的东西。
var GV = 'global_var'
function changeVar(lv) {
console.log('inside function lv is '+lv);
lv='local_var'
console.log('after changing value lv is '+lv);
console.log('inside function GV is '+GV);
}
console.log('before function GV is '+GV);
changeVar(GV);
console.log('after function GV is '+GV);
如果我在 lv 的范围之上运行代码是本地的,并且任何修改都不会更改全局范围内的 GV,但是如果我将 GV 更改为数组并在同一函数中修改其元素之一,那么全球 GV 也发生了变化。这是为什么?我有一种感觉,它可能与实例有关,但我不明白。
var GV = [1,5,8]
function changeVar(lv) {
console.log('inside function lv is '+lv);
lv[1]=[0]
console.log('after changing value lv is '+lv);
console.log('inside function GV is '+GV);
}
console.log('before function GV '+GV);
changeVar(GV);
console.log('after function GV is '+GV);
我考虑过提升(所以如果 ls 在函数内部声明为一个新变量),但如果是因为这样,函数内部的第一个 console.log 不应该显示未定义吗?
【问题讨论】:
-
这种行为与作用域无关,纯粹是因为在 JS 中对象(例如数组)是“通过引用”传递和分配的,所以当你改变一个“副本”时,你会改变所有引用的变量相同的值 - 这就是第二个示例中
LV和GV发生的情况。在第一个示例中没有发生这种情况的原因是它重新分配给LV,而不是对其进行变异。 (请注意,即使您愿意,也不能改变字符串等原始值。) -
非常感谢 :)
-
将此视为 Robin 回答的旁注,尽量避免使用“var”,而是尝试使用块范围等效项,如“const”和“let”,这可以帮助您编写更严格的代码。
-
是的,我只是在试验,但这是一个好点 :)
标签: javascript scope global-variables local-variables