首页 > 代码库 > 如何理解javaSript中函数的参数是按值传递

如何理解javaSript中函数的参数是按值传递

本文是我基于红宝书《Javascript高级程序设计》中的第四章,4.1.3传递参数小节P70,进一步理解javaSript中函数的参数,当传递的参数是对象时的传递方式。

(结合资料的个人理解,有不正确的地方,希望大家指出,谢谢啦!)

参考的资料有:

https://github.com/simongong/js-stackoverflow-highest-votes/blob/master/questions21-30/parameter-passed-by-value-or-reference.md

https://segmentfault.com/a/1190000005177386

首先,我们简单理解一下什么是按值传递和按引用传递。

按值传递:把函数外部的值复制给函数内部的参数,相当把值从一个变量复制到另一个变量,这两个变量是互不影响的。(传内存拷贝)

eg:

1 function addTen(num){
2         num+=10;
3         return num;
4     }
5     var count=20;
6     var result=addTen(count);
7     alert(count);//20
8     alert(result);//30

 

按引用传递:传内存指针。

  按引用传递,当向参数传递值时,传递的是这个值在内存中的地址,所以在局部作用域中对值进行的操作会反映在全局作用域中。因为它们是对同一地址进行操作的。

 

 

 

但是,ECMAScript中,当向参数传递引用类型的值时,如果直接说是“按值传递”,那么以下代码执行的结果会让我们有些疑惑:

code1:

1 function setName(obj){
2         obj.name="Linshuling";
3     }
4    var person=new Object();
5    setName(person);
6    alert(person.name);//Linshuling

但是如果因为上面的这种情况就断定不是“按值传递”,而是“按引用传递”的话,我们又无法解释下面的这种情况:

code2:

1  function setName(obj){
2           obj.name="Linshuling";
3           obj=new Object();
4           obj.name="lin";
5       }
6       var person=new Object();
7       setName(person);
8     alert(person.name);//Linshuling

 

所以,我在网上找到了另一种解释:

Call-by-sharing   传引用的拷贝。

当我重新阅读书中对此的解释时,发现这样的说法是符合的,书中的解释时这样的:在向参数传递引用类型的值时,会把这个值在内存中地址复制给一个局部变量,因此这个局部变量的变化会放映在函数外部。(注意此处,是把地址复制给一个局部变量,而不是直接传地址。)

我是这么理解的:

技术分享

 

结合上面理解code1,code2:

在code1中 obj.name="Linshuling";会反映到全局作用域,是因为实际上是对同一地址进行了操作,如上图,即复制后的a的地址add,由于add和ad是一样的值,所以也会影响a。但是在code2中  obj=new Object(); obj.name="lin"; 这里实际上是在函数内部重写了obj,即重写了add,但是是不影响ad的,add和ad的值是完全独立的(从这里出发理解函数的参数传递是按值传递的,也就好理解了!),而且这里重新定义的obj是一个局部变量,这个局部变量会在函数执行完毕后立即被销毁。

 

如何理解javaSript中函数的参数是按值传递