深入理解 JS 参数传递

由于在 JavaScript 中访问变量的方式有两种:按值访问及按引用访问,那么参数传递是以是什么方式传递的呢?
在《JavaScript 高级程序设计》一书中有写到:
ECMAScript 中所有函数的参数都是按值传递的。也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,则如同引用类型变量的复制一样。
(P70 页)
那么我们就通过几个例子来分析看一下。
传入基本类型
这里我们声明了一个变量 count,然后调用 add 函数,传入 count,此时相当于把 count 复制了一份,赋值给 num,各自占用单独的空间:

因此在 add 函数内部对 num 的修改,并不会影响到原来的 count:

上面演示的是一个基本类型,那么如果传入的是一个引用类型呢?
传入引用类型
首先来看第一个例子:
通过运行结果,看起来传入引用类型貌似也是复制了一份,对原来的并未有影响?
首先看一下引用类型的存储方式:

引用类型在栈空间中存储的实际上是一个指针,指向堆内存中实际存储的位置。
当 obj 传入 foo 函数内部,对于值也是复制了一份,只不过是指向同样的堆空间,他们的引用还是一样的。
但是在 foo 函数内部,对于 o 的修改实际上是赋值操作,直接覆盖,指向了新的地址,因此对于 obj 并没有影响,如图所示:

然后再来看下一个例子:
由于在函数 foo 内部执行 o.a = 2
,修改的是堆空间中的对象,而这个对象和 obj 共享,因此也影响到了 obj 的变化:

总结
通过以上分析,我们可以知道 JavaScript 中的所有参数传递均为值传递,存在一个值复制的过程,基本类型直接复制出新的值,而引用类型复制的是指针,指向堆空间中的实际存储对象。
思考:可以分析下如下代码中各个 console.log
的输出结果
Ok, 以上就是关于 JS 中参数传递的一些总结😯。
Photo by Brooke Cagle on Unsplash
版权声明: 本文为 InfoQ 作者【墨子苏】的原创文章。
原文链接:【http://xie.infoq.cn/article/fa86ad380a594d10970dc1c6f】。文章转载请联系作者。
评论