之前看了很多人的解释,说js中,函数的参数传递都是值传递中不理解。
他们无非举了两个例子
在这两个例子中,第二个例子可以看出参数是由值传递的。因为函数内对象的变化没有影响到函数外对象的变化。但是在第一个例子中,我们却发现,函数内和函数外都指向了一个地址。但是博主并没有说明
既然是值传递,为什么参数里面的改变却影响了外面的值。博主只解释了第二个例子是值传递,却没有解释第一个例子为什么会出现这样的原因,只是一句两个变量指向一个对象
就一笔带过,我觉得这个并没有解决大多数人的理解。所以我觉查看了js高级程序设计的原话。
《js高级程序设计》上是这样叙述参数传递的:所有函数的参数都是按值传递的
这段话摘抄自第四章的第一章节的传递参数。
这里解释一下,值传递。值传递就是传进来的参数中,我们传递的是一个值,而不是一个指针。
其实。为什么第一个例子中,两个变量指向的是一个对象。原因很简单,就是因为这里的参数传递的本来就是一个地址。这似乎和之前说的所有参数都是值传递相违背。觉得既然是值传递应该传递的是一个对象,然后在参数中建立一个这个对象的副本。其实这是一种错误的理解。
这里需要解释一下值传递,什么是值传递。值传递就是说,参数传递的是其中的值,然后这个值在函数中会建立一个副本,在函数内操作参数的其实是这个副本,而不是函数外传递的变量。
而js函数机制中,函数传递的参数,会把参数的值存储在arguments(这个数组是函数对象自带的数组,用来保存参数值)这个数组中,我们操作的参数,其实是这个数组中的值。这里就从本质上解释了js函数是值传递。
了解这个我们就可以说为什么第一个例子中所出现的现象了。因为,对象参数传递的,本身就是一个地址,他并不是一个对象。
这里可能还会疑惑,既然是传递的地址为什么还叫做值传递。
我们可以通过一幅图来理解
在这里,当a被当做参数时,a中的值也就是地址,被传递进了arguments这个数组中,而值传递和引用传递,指的其实对于这个地址来说的。
值传递, 就是传递a的值,a的值其实就是指向Object的地址。
如果是
引用传递,传递的是a的地址,也就是指向a的地址。如果了解c语言就可以对这个明白了。
a中保存的是指向对象的一个指针,在引用传递中,会传递一个指向a的指针。
所以这就解释了为什么会出现两个例子中这个看似很矛盾的的原因了。
值传递还是引用传递,他所说的并不是a指向的对象的传递方式,而仅仅是a的传递方式。
这是自己的理解,我觉得这样的理解对我来说才彻底解释了我之前感觉两个例子的矛盾的原因