JavaScript全局变量重赋值问题及示例底层原理解析
JavaScript中全局变量与函数参数的常见困惑解答
嘿,我明白你这种抓耳挠腮的困惑——JavaScript的变量作用域和引用传递有时候确实像个藏在代码里的小陷阱,咱们一步步把这两个问题掰扯明白。
疑问1:为何无法通过函数的参数重赋值全局变量?
这得从变量作用域和参数的本质说起:
当你把全局变量作为参数传入函数时,函数会自动创建一个和参数名同名的局部变量。这个局部变量拿到的是全局变量的「值」——如果是字符串、数字这类基本类型,就是值的拷贝;如果是数组、对象这类引用类型,就是内存引用地址的拷贝。
但重点来了:当你在函数里给这个参数重赋值时,本质上是把这个局部变量的指向给改了,和原来的全局变量彻底脱钩了。举个直白的例子:
let globalVar = "我是全局变量"; function changeParam(param) { // 这里是给局部变量param重赋值,和全局变量globalVar完全无关 param = "我是新值"; } changeParam(globalVar); console.log(globalVar); // 输出:我是全局变量
简单说:参数是函数的“私有变量”,重赋值参数只是修改这个私有变量的指向,根本碰不到外部的全局变量。
疑问2:三个示例为何输出完全不同?
先把三个典型的对应示例补全,再逐个拆解原因:
示例1:直接修改全局变量(结果符合预期)
var myArray = [1, 2, 3, 4, 5]; function alterArray(){ myArray = [5, 4, 3, 2, 1]; return myArray; } alterArray(); console.log(myArray); // 输出:[5, 4, 3, 2, 1]
原因:函数里直接访问的是全局作用域下的myArray,你重赋值的是全局变量本身,相当于把全局变量的指向从旧数组改成了新数组,外部自然能看到变化。
示例2:把全局变量作为参数传入,重赋值参数
var myArray = [1, 2, 3, 4, 5]; function alterArray(arr){ arr = [5, 4, 3, 2, 1]; return arr; } alterArray(myArray); console.log(myArray); // 输出:[1, 2, 3, 4, 5]
原因:这里的arr是函数的局部参数,一开始它拿着myArray的引用地址,但当你给arr重赋值为新数组时,arr就指向了一块全新的内存地址,和原来的全局myArray的引用彻底没关系了。所以全局变量的指向没被改动,输出还是原来的数组。
示例3:把全局变量作为参数传入,修改参数的内部元素
var myArray = [1, 2, 3, 4, 5]; function alterArray(arr){ arr.reverse(); // 修改数组的内部元素 return arr; } alterArray(myArray); console.log(myArray); // 输出:[5, 4, 3, 2, 1]
原因:这里你没有给arr重赋值,而是通过它拿到的引用地址,直接修改了内存里数组的内容(反转元素)。因为arr和全局myArray指向的是同一块内存里的数组,所以全局变量的内容也跟着变了。
核心总结
- 直接操作全局变量:会直接改变全局变量本身。
- 给函数参数重赋值:只修改局部变量的指向,不影响外部全局变量。
- 通过参数的引用修改对象/数组的内部内容:会影响全局变量,因为两者指向同一个内存对象。
内容的提问来源于stack exchange,提问作者Meng
相关产品推荐
相关产品推荐

