js传参是按值传递还是按引用传递?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js传参是按值传递还是按引用传递?相关的知识,希望对你有一定的参考价值。

 数据类型

基本数据类型

number、string、boolean、null、undefined   基本数据类型的值保存在栈中;

引用数据类型

array、object、function 等对象,引用类型的数据保存分为两部分:

  • 地址
  • 值  

其中栈中是保存地址的引用,堆中保存真正的值  如

技术分享

 

什么是按值传递?什么是按引用传递?

按值传递(call by value):函数的形参是被调用时所传实参的副本,修改形参的值并不会影响实参。

按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被修改,实参也会被修改,同时两者指向相同的内存地址。

Js传递方式

参数是基本数据类型:

1     var a = 10;
2     function add(a) {
3         a = 20;
4         console.log(a);//20
5     }
6     add(a);
7     console.log(a);//10

变量a在add 内部改变了值,并没有影响到外部的a变量;

参数是引用类型:

1 //引用类型
2     var person = {name: ‘joel‘, age: 11}
3     function foo(o) {
4         o.name = ‘alen‘;//改变对象的值
5         o = {name: ‘elire‘}//改变对象的地址
6         console.log(o.name); //elire
7     }
8     foo(person);
9     console.log(person.name);//alen

如果是按照引用传递,传进去的o对象跟外部的person对象指向的内存应该是同一个,但是foo()内部o.name 是elire,外部的person.name 是alen,所以尽管是引用类型数据传递的时候也不是按引用传递;

继续看下面demo:

 1     var v1 = []
 2     var v2 = {};
 3     var v3 = {};
 4     function demo1(v1, v2, v3)
 5     {
 6         v1 = [1];
 7         v2 = [2];
 8         v3 = {a:3}
 9     }
10     demo1(v1, v2, v3);
11     console.log(v1); // 空白
12     console.log(v2); // [object Object]
13     console.log(v3.a); // undefined

由此可见:v1、v2、v3 都没有被改变,v1 仍然是零个元素的数组,v2、v3 仍然是空白的对象。即引用类型数据也是按照值传递的,先是拷贝了栈中的地址,然后在demo1()内部改变了地址的指向。

但是引用类型按值传递与基本类型数据按值传递还是有区别的。

基本数据类型,如数字、字符串是把值直接复制进去了,而引用类型 如数组、对象是把变量地址复制进去。

前面我们让 v1、v2、v3 作为参数进入函数后,就有了地址副本,这些地址副本的指向和外面的 v1、v2、v3 的地址指向是相同的。但我们为 v1、v2、v3 赋了值,也就是说我们把地址副本的指向改变了,指向了新的数组和对象。这样内部的 v1、v2、v3 和外部的 v1、v2、v3 就完全断了。
如果我们不赋新值,而是直接操作它,那么传进去的仍然是和外面的 v1、v2、v3 指向的同一块数组或对象,因为我们没有改变他们的指向。

如:

 1     var v1 = []
 2     var v2 = {};
 3     var v3 = {a:0};
 4     function demo2(v1, v2, v3)
 5     {
 6         v1.push (1);
 7         v2.a = 2;
 8         v3.a = 3;
 9     }
10 
11     demo2(v1, v2, v3);
12     console.log(v1); // 1
13     console.log(v2.a); // 2
14     console.log(v3.a); // 3

总结

基本数据类型,如数字、字符串是把值复制进去,而引用类型 如数组、对象是把变量地址复制进去,

如果没有改变传进去的地址指向,那么它们都是指向同一个内存地址;

如果改变了地址指向那么它们跟外部的对象是两个独立的对象,互不干扰;

 

以上是关于js传参是按值传递还是按引用传递?的主要内容,如果未能解决你的问题,请参考以下文章

JS基础类型和对象,分别是按值传递还是按引用传递?

JS是按值传递还是按引用传递

JS基础之传参(值传递对象传递)

JS中函数参数值传递和引用传递

java中的参数传递是按引用传递还是按值传递

python中的“引用”和C++的引用