前端开发笔记JavaScript 进阶营程序员

JavaScript值传递 or 引用传递?

2018-10-27  本文已影响6人  岛在深海处

对于函数的值传递和引用传递一直有点模糊理解。今天正好有空来扒一扒,首先看下关于这两个词的解释:

值传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 ——百度百科

引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。 ——百度百科

从定义来看,不管是值传递还是引用传递,都是针对参数来说的,也就是说只在变量当成参数传给函数时,才适用是值传递还是引用传递的讨论范围。

我们来看段代码:

function setName(arg){
  arg.name = "Nicholas";
  arg = new Object();//将函数局部变量obj指向另一个新的变量
  arg.name = "Greg";
}
var person = new Object();
setName(person);//传递栈中的指针值
console.log(person.name);//Nicholas

用堆栈图表示:


函数的引用传递.png

通过堆栈图发现,javaScript在传递参数的时候实际上是把实际参数的地址传递到函数中。这跟我之前的理解就有点冲突了,之前没理清值传递与引用传递的概念,一直认为函数在传递参数的时候都是值传递。那照这样说,javaScrpit参数到底存不存在真正的值传递呢?

以我个人理解来看,并不存在,因为就算是基本数据类型当参数内存中也没必要额外复制一份地址,因为基本类型的值是不可变的。

我们来看以下代码:

function addTen(arg) {
   arg = arg + 10;
   return arg;
}
var count = 20;
var result = addTen(count);
console.log(count); // 20
console.log(result); // 30

从节约内存的角度来讲,应该是直接将参数arg指向实际参数count的地址,当有新值赋给arg时才将arg指向新值的地址。而不是一开始就在内存中造两个20。

由于基本类型的值是不变的,我们无法直接修改其值,所以只能用赋值符号("=")来赋予新的值。旧值如果没有被其他变量引用,就会被回收。

对应的堆栈图我们画出来:

基本类型参数传递.png

我们把javaScript参数分为两类:

基本类型与引用类型

基本类型:String,Number,Boolean,Null,Undefined。
引用类型:Array、Object、Function、Date等有多个值构成的可变长度的复杂类型。

网上很多文章都把基本类型的函数传参解释为值传递,这样理解其实也是可以的,结果都一样,本着节省内存的角度,我认为引用传递更合理。

关于JavaScript变量赋值在内存中存储的问题可以看这篇文章:
javaScript变量在内存中的存储问题

上一篇 下一篇

猜你喜欢

热点阅读