javascript - js 全局和局部范围
问题描述
我正在对范围进行一些实验,但偶然发现了这个我不明白的东西。
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 不应该显示未定义吗?
解决方案
这是因为当 时var GV = 'global_var'
,GV 变量包含实际的字符串 'global_var'。当您将 GV 传递给 时changeVar
,它是按值传递的,即在changeVar
函数范围内,会创建一个新变量lv
,并将值“global_var”复制到新的新变量中。调用该函数后,立即出现以下状态:
GV 仍然包含“global_var”,而 lv 包含“global_var”的副本,完全相同的值。
现在在本地范围内,lv='local_var'
并且 lv 已更新,但 GV 保持不变。因此,退出函数后,GV 保持不变,因为它位于完全不同的内存位置。
现在让我们看看第二种情况,其中GV = [1,5,8]
. 在这种情况下,GV 被分配了一个 JavaScript 数组,记住,数组是对象。对象有引用,因此 GV 变量包含对 [1, 5, 8] 数组的引用。现在,一旦你调用函数changeVar
,将 GV 作为参数传入,数组的引用就会被传递并存储在lv
. 现在在函数调用之后,这是状态:
GV 包含对 [1, 5, 8] 的引用,而 lv 也包含对 [1, 5, 8] 的相同引用。所以它是按值传递引用,即传递引用,而不是整个数组作为副本传递给函数。在函数内部,当你执行 时lv[1]=[0]
,它会将内存中的原始数组更新为 [1, 0, 8]。
当您退出函数时,GV 仍然指向原始数组,而当您打印 GV 时,它会显示更新后的数组 [1, 0, 8]。
推荐阅读
- python - 如何在特殊位置获取子字符串
- r - 使用 pCADFtest 存在横截面相关性的面板单位根
- node.js - 处理 Node 应用程序中的 CORS 错误
- google-apps-script - 当列中的值发生变化并通过 IF 测试时,从 Google 电子表格发送电子邮件
- javascript - 在javascript中对列表列表进行排序
- visual-studio-code - 切换webview时输入无法聚焦
- amazon-web-services - 在 S3 上传时生成随机文件名
- spring-integration - 需要带有轮询器的有序集群入站通道适配器 [不适用于 ftp]。还是找不到
- javascript - 将 JSON 发送到服务器
- sql - DAX 中 date1 和 date2 (Sql) 之间的 dateX 右连接