转: https://segmentfault.com/a/1190000005177386

众所周知,JavaScript中参数是按值传递的。与访问变量不同,基本类型和引用类型的参数在传递时都如同变量的复制。

但是我们在使用引用类型的参数传递时,经常会发现在函数内改变引用类型参数(如对象)会在函数外反映出来,这种情况貌似与“按值传参”的思想不符?
我本人在这个坑上也摔过很多次,最近遇到了一个新词:call by sharing(按共享传参)让我对这个问题有了比较深刻的认识。分享给对这个问题有误解的童鞋们。。。
先大概介绍按值传参

基本类型

基本类型的参数传递比较简单,示例代码

function add(num){
num+=10;
console.log(num);
}
var str=10;
add(str);//20
console.log(str);//10

str的值复制给了函数add内部的局部变量num,所以在函数内部改变num的值并不会影响外部str的值。

引用类型

红宝书上有这么一句话:在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反应函数外。

用两段代码来说明:

function setName1(obj){
obj.name="Mike";
return obj;
}
var person=new Object();
setName1(person);
console.log(person.name);//'Mike'

这段代码表面上看:函数内部的改变影响了函数外,难道是按引用传递?再看下面这段代码:

 function setName2(obj){
obj.name="Mike";
obj={name:"Tom"};
return obj;
}
var person=new Object();
setName2(person);
console.log(person.name);//'Mike'

这个情况就比较有趣了,如果是按引用传递的,函数内函数外始终访问用一个引用,最后的结果应该是“Tom”才对。

再回到之前提到的:在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反应函数外。
其实这句话从另一个角度讲,就是call by sharing(共享传参)的定义。

先看一下ECMAScript中对call by sharing的定义

The main point of this strategy is that function receives the copy of the reference to object. This reference copy is associated with the formal parameter and is its value.
Regardless the fact that the concept of the reference in this case appears, this strategy should not be treated as call by reference (though, in this case the majority makes a mistake), because the value of the argument is not the direct alias, but the copy of the address.
The main difference consists that assignment of a new value to argument inside the function does not affect object outside (as it would be in case of call by reference). However, because formal parameter, having an address copy, gets access to the same object that is outside (i.e. the object from the outside completely was not copied as would be in case of call by value), changes of properties of local argument object — are reflected in the external object.
其实这段话,特别是标粗的地方说明的就是:引用类型把在内存中的地址复制给了函数中的局部变量。
所以出现会两种情况:

    • 改变引用类型的属性
      当在函数中改变引用类型(如对象)的属性时,是在同一个内存地址区域进行操作,所以会在函数外反映出来。如setName1

    • 列表项目
      在函数内,对形参进行了重新复制,即改变了形参的引用,(内存中的地址已经改变),与实参引用已经完全不一样了,所以不会对函数外引用类型变量参数产生影响,如setName2.

[05] call by sharing || 共享参数的更多相关文章

  1. 共享参数ContentProvider 类与数据库绑定,如何通过共享参数测试类,测试数据库的增删改查功能

    Intent可以传一个对象 当两个界面之间跳转时,需要传递一个对象过去,是通过使用Bundle类,并且实体类需要serializable实现序列化,传递方法如下: 定义一个静态常量作为key值 pub ...

  2. Android 开发笔记___存储方式__共享参数__sharedprefences

    Android 的数据存储方式有四种,这次是[共享参数__sharedprefences] 听起来挺别扭的,平时看到的app里面,当用户删除了一些软件以后下次安装,发现原来的设置还在,这种情况就是把一 ...

  3. Revit通过API创建共享参数

    Revit共享参数是通过创建一个.txt类型的文件来保存相关信息,一旦与项目保存完毕之后,共享参数也就变成了项目参数(项目参数无法通过API创建),项目参数是保存在Revit项目里面的,所以此时这个. ...

  4. Kotlin入门(25)共享参数模板

    共享参数SharedPreferences是Android最简单的数据存储方式,常用于存取“Key-Value”键值对数据.在使用共享参数之前,要先调用getSharedPreferences方法声明 ...

  5. Revit API 操作共享参数和项目参数

    1.获取共享参数 private string GetSharInfo(Autodesk.Revit.ApplicationServices.Application revitApp) { Strin ...

  6. 数据存储之 SharedPreference 共享参数 (转)

        在上一讲中,我们学习了如何将数据存储在SD卡中[数据存储之File文件存储 [即SD卡的写入与读取]],这是一种存储方式,这一讲我们来学习一下使用SharedPreferences存储数据. ...

  7. android 开发-数据存储之共享参数

    android提供5中数据存储方式 数据存储之共享参数 内部存储 扩展存储 数据库存储 网络存储  而共享存储提供一种可以让用户存储保存一些持久化键值对在文件中,以供其他应用对这些共享参数进行调用.共 ...

  8. Android 共享参数 SharedPreferences

    完成共享参数的读写 public class SharedPreference { private Context context; public SharedPreference(Context c ...

  9. Android数据存储之共享参数SharedPreferences

    SharedPreferences是Android的一个轻量级存储工具,采用的存储结构是Key-Value的键值对方式,类似于Java的Properties类,二者都是把Key-Value的键值对保存 ...

随机推荐

  1. .Net 面试题 汇总(三)

    101.ASP.net的身份验证方式有哪些?分别是什么原理? 答:Windwos(默认)用IIS... From(窗体)用帐户 Passport(密钥) 102.在.net中,配件的意思是? 答:程序 ...

  2. java程序——两数的加减乘除

    import javax.swing.JOptionPane; // import class JOptionPane public class Elementary { public static ...

  3. js字符串操作函数

    js字符串函数 JS自带函数 concat 将两个或多个字符的文本组合起来,返回一个新的字符串. var a = "hello"; var b = ",world&quo ...

  4. 从装机到配置-CentOS6.5

    L006课程结束后的总结 首先:系统(cat /etc/redhat-release):CentOS release 6.5 (Final) 版本(uname -r):2.6.32-431.el6.x ...

  5. HMM相关文章索引

    HMM相关文章索引 1条回复 HMM系列文章是52nlp上访问量较高的一批文章,这里做个索引,方便大家参考. HMM学习 HMM学习最佳范例一:介绍 HMM学习最佳范例二:生成模式 HMM学习最佳范例 ...

  6. React开发时候注意点

    JSX 使用jsx的使用,用一个{}包裹起来,例如 const method = {<div> 123 </div>} 使用()小括号,防止分号自动插入 const eleme ...

  7. 虚拟现实-VR-UE4-创建C++版工程

    首先,创建C++版本的UE4 项目工程,我使用的是4.12.3版本,据了解,新版本后面的编译都是vs2015 所以,想要创建C++版本的工程,就需要安装vs2015 至于vs2015的安装,自己百度吧 ...

  8. 第八篇Python基本数据类型之列表、元组与字典

    列表 写在最前,必须要会的:append(),extend(),insert(),索引,切片,循环 list  是一个类,是个对象 列表用 方括号[]括起来的,[]内以逗号分割每个元素,列表中的元素可 ...

  9. Python全栈 MongoDB 数据库(数据的修改)

    修改操作符的使用   $set 修改一个域的值,增加一个域   阿哲年龄修改为33 db.class1.update({name:'阿哲'},{$set:{age:33}})   如果sex域不存在则 ...

  10. 定时爬虫抓当日免费应用:Scrapy + Tkinter + LaunchControl

    花了个周末学了下Scrapy,正好一直想买mindnode,于是顺手做了个爬虫,抓取爱范儿每天的限免应用信息. Thinking 大概思路就是使用LaunchControl每天定时(比如早上9点50, ...