首页 > 解决方案 > 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 不应该显示未定义吗?

标签: javascriptscopeglobal-variableslocal-variables

解决方案


这是因为当 时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]。


推荐阅读