js和其他大部分语言一样,有基本类型和引用类型。因此访问变量就有按值按引用两种方式,但是传参的时候却只能按值传递。基本类型作为参数时按值传递自然无可厚非,但引用类型作为参数也按值传递就让人有点困惑了。

看下面这个例子:

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

以上代码创建了一个名为person的对象,并且将其作为参数传给了setName函数。我们在函数内部给传进来的对象添加了一个name属性并赋值,之后在函数外部访问person.name,会弹出"Sim"。一般我们都说,若是按值传递的话,形参在函数内的变化不会影响到实参的变化,但这个例子中,函数内部给形参加上的属性在实参中也有此属性。这会让人产生一种误解,感觉引用类型传参貌似是按照引用传递的啊!

下面再给出一个例子:

var obj1 = {
value:'111'
}; var obj2 = {
value:'222'
}; function changeStuff(obj){
obj.value = '333';
obj = obj2;
return obj.value;
} var foo = changeStuff(obj1); console.log(foo);// '222' 参数obj指向了新的对象obj2
console.log(obj1.value);//'333'

上面例子打印出了形参obj和实参obj1的value值我们可以清楚的看到,这两个value值并不一样,因此可以证明引用类型的参数并非是按照引用传递的。

至于为什么会出现这种情况,那就有必要来理解一下js中的数据存储与访问的机制了。

声明变量时的内存分配

基本类型:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。这是因为这些原始类型占据的空间是固定的,所以可将他们存储在较小的内存区域 – 栈中。这样存储便于迅速查寻变量的值。

引用类型:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存地址。这是因为:引用值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反,放在变量的栈空间中的值是该对象存储在堆中的地址。地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响。

复制变量时的不同:

基本类型:在将一个保存着原始值的变量复制给另一个变量时,会将基本类型的副本赋值给新变量,此后这两个变量是完全独立的,他们只是拥有相同的value而已。

引用类型:在将一个保存着对象内存地址的变量复制给另一个变量时,会把这个内存地址赋值给新变量,也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个作出的改变都会反映在另一个身上。(这里要理解的一点就是,复制对象时并不会在堆内存中新生成一个一模一样的对象,只是多了一个保存指向这个对象指针的变量罢了)
 
在清楚了这些之后,我们再来结合之前的那个例子来看:
可以看到之所以给形参加上属性之后,实参也会带有此属性。那是因为实参,形参都是指向储存在堆内存中的对象的指针。我们改变的其实是堆内存中的对象的属性,obj和obj1都没有发生改变。但当执行了obj = obj2之后,相当于将obj指向了obj2所指向的value值为‘222'的对象。
搞清楚了这些,估计你就能理解为什么引用类型的传参方式是按值传递了吧!

js按值传递还是按引用传递?的更多相关文章

  1. js按值传递和按引用传递

    摘要:js的数据类型有种划分方式为 原始数据类型和 引用数据类型. 原始数据类型 存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置.栈区包括了 变量的标识符和变量的值. ...

  2. JS是按值传递还是按引用传递?【转载】

    最近遇到个有趣的问题:“JS中的值是按值传递,还是按引用传递呢?” 在分析这个问题之前,我们需了解什么是按值传递(call by value),什么是按引用传递(call by reference). ...

  3. Java参数按值传递?按引用传递

    有时候在想,java在调用方法时候究竟是按值传递还是按引用传递,之前有人说是基本数据类型按值传递,引用类型按引用传递.一时间,似乎都有道理. 笔者在此不追究字眼上的辨别识字能力,把自己对这个问题的理解 ...

  4. JavaScript中函数参数的按值传递与按引用传递(即按地址传递)

    首先声明一句:JavaScript中所有函数的参数都是按值传递的!不存在按引用传递! 在讲传递参数之前我们先来讲一下指针. 学过C指针的应该都知道,指针变量中保存的是一个地址,程序可以根据所保存的地址 ...

  5. PHP中对象是按值传递还是按引用传递?

    1.首先,什么是按值传递和按引用传递? 按值传递就是仅仅把值传递过去,相当于传递的是值的拷贝,而按引用传递传递的是内存的地址. 在 PHP5 中,如果按引用传递,就是将 zval 的地址赋给另一个变量 ...

  6. Java的按值传递和按引用传递解说

    在网上看到的一个帖子解释Java的按值传递和按引用传递,感觉挺全面,就转过来,以供以后学习参考: 1:按值传递是什么 指的是在方法调用时,传递的参数是按值的拷贝传递.示例如下: public clas ...

  7. 编程细节 —— 按值传递、按引用传递(final、const)

    System.out,out 是 System 类内定义的静态 final PrinterStream 变量: public final class System { ... public final ...

  8. 转------深入理解--Java按值传递和按引用传递

    引言 最近刷牛客网上的题目时碰到不少有关Java按值传递和按引用传递的问题,这种题目就是坑呀,在做错了n次之后,查找了多方资料进行总结既可以让自己在总结中得到提高,又可以让其他人少走弯路.何乐而不为? ...

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

    按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本.修改形参的值并不会影响实参. 按引用传递(call by reference)时,函数的形参接收实参的隐式 ...

随机推荐

  1. VC C运行时库(CRTL)的几个版本及选用

    分类: Windows 2008-12-23 10:01 987人阅读 评论(0) 收藏 举报ciostreammfclibrary多线程import最近做项目碰到了一个关于在动态库中使用MFC以及在 ...

  2. MySQL information_schema表查询导致内存暴涨

    case:下面的一条sql语句,导致mysql实例内存暴涨: select * from tables where table_name not in(select table_name from p ...

  3. MySQL配置文件-my.ini

    下面允许我介绍一下MySQL的my.ini配置文件: my.ini是什么? my.ini是MySQL数据库中使用的配置文件,修改这个文件可以达到更新配置的目的. my.ini存放在哪里? my.ini ...

  4. javascript 中concat与push的区别

    1. push 遇到数组参数时,把整个数组参数作为一个元素:而 concat 则是拆开数组参数,一个元素一个元素地加进去. 2. push 直接改变当前数组:concat 不改变当前数组. 总结:如果 ...

  5. 兼容ie\firefox\chrome的cursor

    cursor:hand 与 cursor:pointer 的效果是一样,都像手形光标. 但用FireFox浏览时才注意到使用cursor:hand在FireFox.chorme里并被支持.cursor ...

  6. Fiddler On Linux

    参考链接: http://www.development-cycle.com/2013/08/debugging-web-applications-with-fiddler-on-linux/ htt ...

  7. Maximum Flow Exhaustion of Paths Algorithm

    参考youtube上的视频: http://www.youtube.com/watch?v=sxyCzzUuXLo 笔记: 只要是那条路上为0后,就不会再走那条路. 所以没有S->U->W ...

  8. cefSharp 设置运行时系统语言

    在使用用CefSharp使用过程中,系统用了很多第三方控件.这些控件很多能够根据浏览器设置的语言来进行控件展示对应语言. 在cefSharp可以设置系统语言,代码如下: CefSharp.Settin ...

  9. 设计模式_Adapt

    一个形象的例子: (ADAPTER)在朋友聚会上碰到了一个美女Sarah,从香港来的,可我不会说粤语,她不会说普通话,只好求助于我的朋友kent了,他作为我和Sarah之间的Adapter,让我和Sa ...

  10. Codeforces Round #335 (Div. 2)B. Testing Robots解题报告

                                                                                               B. Testin ...