[05] call by sharing || 共享参数
转: 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 || 共享参数的更多相关文章
- 共享参数ContentProvider 类与数据库绑定,如何通过共享参数测试类,测试数据库的增删改查功能
Intent可以传一个对象 当两个界面之间跳转时,需要传递一个对象过去,是通过使用Bundle类,并且实体类需要serializable实现序列化,传递方法如下: 定义一个静态常量作为key值 pub ...
- Android 开发笔记___存储方式__共享参数__sharedprefences
Android 的数据存储方式有四种,这次是[共享参数__sharedprefences] 听起来挺别扭的,平时看到的app里面,当用户删除了一些软件以后下次安装,发现原来的设置还在,这种情况就是把一 ...
- Revit通过API创建共享参数
Revit共享参数是通过创建一个.txt类型的文件来保存相关信息,一旦与项目保存完毕之后,共享参数也就变成了项目参数(项目参数无法通过API创建),项目参数是保存在Revit项目里面的,所以此时这个. ...
- Kotlin入门(25)共享参数模板
共享参数SharedPreferences是Android最简单的数据存储方式,常用于存取“Key-Value”键值对数据.在使用共享参数之前,要先调用getSharedPreferences方法声明 ...
- Revit API 操作共享参数和项目参数
1.获取共享参数 private string GetSharInfo(Autodesk.Revit.ApplicationServices.Application revitApp) { Strin ...
- 数据存储之 SharedPreference 共享参数 (转)
在上一讲中,我们学习了如何将数据存储在SD卡中[数据存储之File文件存储 [即SD卡的写入与读取]],这是一种存储方式,这一讲我们来学习一下使用SharedPreferences存储数据. ...
- android 开发-数据存储之共享参数
android提供5中数据存储方式 数据存储之共享参数 内部存储 扩展存储 数据库存储 网络存储 而共享存储提供一种可以让用户存储保存一些持久化键值对在文件中,以供其他应用对这些共享参数进行调用.共 ...
- Android 共享参数 SharedPreferences
完成共享参数的读写 public class SharedPreference { private Context context; public SharedPreference(Context c ...
- Android数据存储之共享参数SharedPreferences
SharedPreferences是Android的一个轻量级存储工具,采用的存储结构是Key-Value的键值对方式,类似于Java的Properties类,二者都是把Key-Value的键值对保存 ...
随机推荐
- Ubuntu14.04安装opencv2.4.13
本文参考相关链接:http://blog.csdn.net/honyniu/article/details/46390097 系 统:Ubuntu 14.04 x64 opencv版本:2.4.1 ...
- Spring 中的文件上传与下载控制
先创建根应用上下文配置,WebDemo/src/main/java/com/seliote/webdemo/config/RootContextConfig.java package com.seli ...
- linux进程 生产者消费者
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> # ...
- Hibernate-ORM:03.Hibernate主键生成策略
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 此篇博客简单记录五种常用的主键生成策咯: 不同的主键生成策略,生成的sql语句,以及hibernate的操作都 ...
- python内置模块[sys,os,os.path,stat]
python内置模块[sys,os,os.path,stat] 内置模块是python自带功能,在使用内置模块时,需要遵循 先导入在 使用 一.sys 对象 描述 sys.argv 命令行参数获取,返 ...
- php用GD库给图片添加水印
php用GD库给图片添加文字水印,整个代码比较简单,DEMO如下: <?php /*打开图片*/ //1.配置图片路径 $src = "aeroplane.jpg"; //2 ...
- html基础问题总结
1.reflow 在CSS规范中有一个渲染对象的概念,通常用一个盒子(box, rectangle)来表示.mozilla通过一个叫frame的对象对盒子进行操作.frame主要的动作有三个: 构造f ...
- 算法搬运之BFPRT算法
原文连接:http://noalgo.info/466.html BFPRT算法,又称为中位数的中位数算法,由5位大牛(Blum . Floyd . Pratt . Rivest . Tarjan)提 ...
- MySQL☞create语句
几种常用的建表语句: 1.最简单的建表语句: create table 表名( 列名1 数据类型(长度), 列名2 数据类型(长度), ... ) 2.带主键的建表语句: CREATE TABLE 表 ...
- LeetCode - 70. Climbing Stairs(0ms)
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb ...