怎么理解JS函数参数是按值传递

1,097 阅读2分钟

怎么理解JS函数参数是按值传递

我们先来看一下这道题:

var a=[1,2,3];
function fn(b){
	b=[4,5,6];
}
fn(a);
console.log(a); //请问a 输出多少
查看答案 [1,2,3]

怎么样你答对了吗?

我们接下来再看一道题:

var obj={
	name:'大雄'
};
function fn(b){
	b.name='小熊'
}
fn(obj);
console.log(obj.name); // 输出多少
查看答案 小熊

你都答对了吗?

接下来我们详解一下为什么

《Javascript 高级程序设计》第三版中有这么一句话 ECMAScript中所有函数的参数都是按值传递的

但是从第二道题我们明显感觉到:就是按照引用传递的啊;首先我们都知道,js 中的类型分为 值类型和引用类型,值类型保存在内存栈中,引用类型保存在内存堆中;

我们看一下 下面的这段代码:

var a={
  name:'大雄'
};
var b=a;
b.name='小熊';
console.log(a.name);
查看答案 小熊

这段代码的执行结果想必大家都知道,因为a 保存的是一个堆指针,b赋值后指向了同一个堆内存;

avatar

我们现在理解下:函数都是按值传递的;

var a={};
function fn(b){
	b=2;
}
fn(a);
//这段代码中函数的参数传递相当于如下代码
function fn(b){
  var b=a; // 对参数进行了复制;在栈内存在开辟了空间;
}

所以说:值传递 可以理解为复制变量值,基本类型复制后俩个变量完全独立;引用类型复制的是引用(即指针),之后的任何一方改变都会映射到另一方;

我相信说到这里第二道题的答案大家应该都明白了,接下来我们看一下第一道题:

// 第一题 相当于如下的代码
function fn(b){
 	var b=a; // b与a 指向了同一个堆内存;
  	b=[4,5,6]; // 并没有改变指针的内容;而是开辟了一个新的堆空间;所以a,b 就不相互影响了; 
};

我们用图说明一下:

avatar

结合图和代码,我们对程序的执行一目了然,相信大家都明白了。

所以说js中函数的参数都是按值传递的

希望能给大家讲明白,有问题欢迎留言,点赞,评论。