传值和传引用一直是各种语言都反复强制又说得让人头晕的一个话题,尤其是新手,在这个问题上浪费很多时间却还是搞不明白
其实只要是传,就是传地址而已
本文忽略变量实际占用的内存大小,比如,一个int, 一个string等,都占用一个内存单位
1. 先看一下变量的声明和赋值:
str1和strArray,都存放一个地址,指向它们表示的变量内存中的位置。忽略变量的类型,应该好明白些,不用数占几个字节。
2. 函数的局部变量
局部变量不是传入的实参,而是实参的一个拷贝,有效期为函数域内部
当调用函数changeContent(str1)时,创建了一个函数changeContent内部的局部变量
strInFun,并把str1的内容,也就是str1变量的地址传给了strInFun。
这时,修改strInFun和strArrInFun有什么后果呢?
如:
function changeContent(strInFun){
strInFun = "string2";
}
str1会不会变呢?当然不会,只是又在内存中创建了一个新变量,内容是"string2",并把地址赋给strInFun而已
一个基本类型的很容易理解,那修改strArrInFun呢?
function changeArrayContent(strArrInFun){
strArrInFun = [
"string4",
"string5",
"string6"
];
}
这样,strArray会不会变呢?一样的道理,只是新创建了一个数组,并把首地址赋给strArrInFun,和strArray一点儿关系都没有
那是什么时候会遇到讨厌的“传值”或“传引用”呢?是在修改strArrInFun[n]的时候!
strArrInFun指向的是和strArray一样的内存位置,如果直接给strArrInFun赋值,是新开辟了一块内存并把地址赋给了strArrInFun
而修改strArrInFun[n]时,修改的是strArray和strArrInFun共同指向的内存位置的内容。这时strArray也会改变
3. 回归
我们的疑惑通常是在函数传入参数时,其实想想,在函数以外的代码世界也是一个意思
有时我们会想,更改一个变量的值,就是改变它那块内存存放的内容,其实不然。在函数外,我们执行:
str1 = "anotherString";
相当于new String("anotherString"),然后把地址给str1
也是开辟一块新内存,存放"anotherString",并把地址赋给str1。原来的那块内存就没用了,会在垃圾回收时被一波带走
给strArray再赋值也是一样的道理。
至于修改strArray[n]是怎么一回事呢?是直接修改了strArray[n]内存中的内容吗?想来也不是,可能是新开辟了一块内存。。。。
好吧,我们就不想它了吧,如果还是没搞明白,记住下面的结论就可以了:
结论:
在函数体外,修改就是修改,修改后就会相应变化;(其实不是内容变了,也是地址变了。。。)
在函数体内,直接修改参数不会对外界产生影响,只有传入Array, Object这样的参数,并修改它们的内部元素(属性)时,外面的变量才会相应地变化。
注:关于内存分配的问题,co也不是很懂,只是觉得这样理解起来很顺畅。欢迎路过的大仙不吝赐教