【Web前端问题】如何理解JavaScript函数中的传递参数?
做前端开发有一段时间,对一些相关概念有了一定的认识。但是,秉着“勿在浮沙筑高台”的态度,我又返回来看了看《JavaScript高级程序设计》这本书。
在看到“变量、作用域和内存问题”这一章时,书中说到:因为访问变量有按值和按引用两种方式,而参数只能按值传递。
示例:
function setName(obj){ obj.name = "Nicholas";
obj = new Object();
obj.name = "Grag";
}
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
其实这个示例,我觉得已经说明了参数的传递的确是按值来传递的,哪怕是一个对象。
但我还是不太明白其中的原理,想象不出在内存中是怎样的。
还望,前端高手能够帮忙解读,解读。
回答:
obj
开始只是person
的一个副本,正如其他引用类型的复制一样,它和person
指向的是同一地址,但obj = new Object();
之后,obj
指向了另一块内存,与person
断开了联系,这就是重写。如果没有obj = new Object();
这一句,alert(person.name);
的结果将会是Grag
回答:
@hiYoHoo 的图已经很简明了,我再来介绍一下 obj 和 person 的本质区别,以下描述比较粗浅,而且比较冗长,见谅,如有遗漏之处请指正。
在 JavaScript 中,从内存分配角度来看,有两种类型的变量:
在栈空间分配的变量(所有值为 number、boolean、string、null、undefined、Symbol 的变量)
在堆空间分配的变量(所有值为数组、对象、函数的变量)
谨记以上两种类型,下面称他们为栈变量和堆变量
那么什么是堆、什么是栈?
从前一座城市,每个出生的人都能分配到一间占地面积固定的房(占用空间已知),每间房子都有它的值(里面居住的人已知)和它的地址(街道门牌号已知),如果一个住户从来不搬家,那么街道办就非常好管理所有的定居居民,办事效率会非常高。
// 创建一个 num 数字,相当于给居民分了一套房子// 变量的内存空间是确定的,4 个字节
// 变量还有个隐含的内存地址,你根据这个地址就可以找到变量 num,取得值 1
var num = 1
// 现在要去找到这个房子,把里面的值打印出来
// 第一件事就是寻址,是编译器帮你自动计算完成的
console.log(num)
从前又有一个游牧民族,这个游牧民族会因为人口、资源、环境等原因迁徙,他们没有固定面积的住房,也不知道他们随时会迁徙到哪里,既然连地址都不知道,更别提想要知道他们里面有哪些人了。这就给城邦的街道办带来了管理麻烦,虽然游牧民族很灵活,他们的生存活动范围可以随意扩大,但是他们经常迁徙,地址经常变动,所以街道办采用的管理策略是:每次游牧民族一迁徙,就给街道办寄一封信,信里面只写着游牧民族首领家的地址,街道办就带人先找到首领家,然后再由首领带领,依次找到所有人的家。
// 创建一个 arr 数组,相当于出现了一个游牧民族var arr = [1, 2, 3, 4]
// 游牧民族增加了新成员
arr.push(5)
// 游牧民族兼并了别的族群
arr.concat([6, 7, 8, 9])
// 因为堆变量在不停地改变空间大小,所以不能跟栈变量生活在一起,会挤死人的
// arr 就是他们的首领,arr[0] 就是第一户,arr[1] 就是第二户
// 所以只要找到首领,就找到所有人了
// 首领聘了一个助理,帮他一起管理所有人
var helper = arr
// 第一户的人长大了
helper[0]++
// helper 叛变了,他现在去另一个游牧民族了
helper = new Array(10)
helper[0]++ // NaN!!!,暴毙身亡
// 栈变量的寻址是编译器帮你完成的
// 而堆变量,寻址是我们自己手动完成的,这就是通过首领,来寻找剩下的所有人的过程
// 首领就是一个`引用`型变量
来看你的代码:
function setName(obj) { // obj 是首领的助理 // 助理帮首领管理 name 家的人
obj.name = "Nicholas";
// 助理叛变了
obj = new Object();
// 助理管理另外一个游牧民族的名为 name 家的人
obj.name = "Grag";
}
// person 就是首领
var person = new Object();
setName(person);
alert(person.name); //"Nicholas"
回答:
只是传了person对象的值进去(也就是所指向的堆),而不是person对象本身,所以里面new的obj修改不了原来的person对象的指向。
以上是 【Web前端问题】如何理解JavaScript函数中的传递参数? 的全部内容, 来源链接: utcz.com/a/134895.html