深入理解JavaScript 参数按值传递


Posted in Javascript onMay 24, 2017

定义
ECMAScript中所有函数的参数都是按值传递的。

什么是按值传递呢?

也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。

按值传递

举个简单的例子:

var value = 1;
function foo(v) {
  v = 2;
  console.log(v); //2
}
foo(value);
console.log(value) // 1

很好理解,当传递 value 到函数 foo 中,相当于拷贝了一份 value,假设拷贝的这份叫 _value,函数中修改的都是 _value 的值,而不会影响原来的 value 值。

引用传递

拷贝虽然很好理解,但是当值是一个复杂的数据结构的时候,拷贝就会产生性能上的问题。

所以还有另一种传递方式叫做按引用传递。

所谓按引用传递,就是传递对象的引用,函数内部对参数的任何改变都会影响该对象的值,因为两者引用的是同一个对象。

举个例子:

var obj = {
  value: 1
};
function foo(o) {
  o.value = 2;
  console.log(o.value); //2
}
foo(obj);
console.log(obj.value) // 2

哎,不对啊,连我们的红宝书都说了 ECMAScript 中所有函数的参数都是按值传递的,这怎么能按引用传递成功呢?

而这究竟是不是引用传递呢?

第三种传递方式

不急,让我们再看个例子:

var obj = {
  value: 1
};
function foo(o) {
  o = 2;
  console.log(o); //2
}
foo(obj);
console.log(obj.value) // 1

如果 JavaScript 采用的是引用传递,外层的值也会被修改呐,这怎么又没被改呢?所以真的不是引用传递吗?

这就要讲到其实还有第三种传递方式,叫按共享传递。

而共享传递是指,在传递对象的时候,传递对象的引用的副本。

注意: 按引用传递是传递对象的引用,而按共享传递是传递对象的引用的副本!

所以修改 o.value,可以通过引用找到原值,但是直接修改 o,并不会修改原值。所以第二个和第三个例子其实都是按共享传递。

最后,你可以这样理解:

参数如果是基本类型是按值传递,如果是引用类型按共享传递。

但是因为拷贝副本也是一种值的拷贝,所以在高程中也直接认为是按值传递了。

所以,高程,谁叫你是红宝书嘞!

深入系列

JavaScript深入系列目录地址: https://github.com/mqyqingfeng/Blog 。

JavaScript深入系列预计写十五篇左右,旨在帮大家捋顺JavaScript底层知识,重点讲解如原型、作用域、执行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、继承等难点概念。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js 调整select 位置的函数
Feb 21 Javascript
js onpropertychange输入框 事件获取属性
Mar 26 Javascript
checkbox全选所涉及到的知识点介绍
Dec 31 Javascript
JavaScript输出当前时间Unix时间戳的方法
Apr 06 Javascript
jQuery实现的网页右下角tab样式在线客服效果代码
Oct 23 Javascript
jQuery图片轮播实现并封装(一)
Dec 03 Javascript
js中开关变量使用实例
Feb 24 Javascript
axios基本入门用法教程
Mar 25 Javascript
vue 项目接口管理的实现
Jan 17 Javascript
微信小程序五子棋游戏的棋盘,重置,对弈实现方法【附demo源码下载】
Feb 20 Javascript
Node.js+ELK日志规范的实现
May 23 Javascript
Vue.js组件props数据验证实现详解
Oct 19 Javascript
详解Angular 4.x NgTemplateOutlet
May 24 #Javascript
javascript简单写的判断电话号码实例
May 24 #Javascript
Angular2搜索和重置按钮过场动画
May 24 #Javascript
深入理解react-router@4.0 使用和源码解析
May 23 #Javascript
angularjs中ng-bind-html的用法总结
May 23 #Javascript
vue.js实现价格格式化的方法
May 23 #Javascript
js编写选项卡效果
May 23 #Javascript
You might like
php代码把全角数字转为半角数字
2007/12/10 PHP
解析如何在PHP下载文件名中解决乱码的问题
2013/06/20 PHP
Thinkphp5框架ajax接口实现方法分析
2019/08/28 PHP
PHP 实现重载
2021/03/09 PHP
ExtJS 2.0实用简明教程 之Ext类库简介
2009/04/29 Javascript
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
2009/09/19 Javascript
asp.net HttpHandler实现图片防盗链
2009/11/09 Javascript
20个非常棒的Jquery实用工具 国外文章
2010/01/01 Javascript
新手常遇到的一些jquery问题整理
2010/08/16 Javascript
高效率JavaScript编写技巧整理
2013/08/23 Javascript
javascript实现图片循环渐显播放的方法
2015/02/24 Javascript
基于jquery实现三级下拉菜单
2016/05/10 Javascript
jQuery UI Bootstrap是什么?
2016/06/17 Javascript
JavaScript实现移动端滑动选择日期功能
2016/06/21 Javascript
JavaScript中日期函数的相关操作知识
2016/08/03 Javascript
Angular2 (RC5) 路由与导航详解
2016/09/21 Javascript
微信小程序视图template模板引用的实例详解
2017/09/20 Javascript
详解vue axios用post提交的数据格式
2018/08/07 Javascript
微信小程序如何实现五星评价功能
2019/10/15 Javascript
JS使用for in有序获取对象数据
2020/05/19 Javascript
[01:24]2014DOTA2 TI第二日 YYF表示这届谁赢都有可能
2014/07/11 DOTA
[57:28]2018DOTA2亚洲邀请赛 4.6 淘汰赛 TNC vs Liquid 第一场
2018/04/10 DOTA
Python中转换角度为弧度的radians()方法
2015/05/18 Python
Python使用email模块对邮件进行编码和解码的实例教程
2016/07/01 Python
python 安装virtualenv和virtualenvwrapper的方法
2017/01/13 Python
深入浅析Python中的yield关键字
2018/01/24 Python
完美解决Pycharm无法导入包的问题 Unresolved reference
2018/05/18 Python
pandas 实现字典转换成DataFrame的方法
2018/07/04 Python
css3图片边框border-image的用法
2017/06/30 HTML / CSS
深入浅析css3 中display box使用方法
2015/11/25 HTML / CSS
马来西亚银饰品牌:JEOEL
2017/12/15 全球购物
世界上最具创新性的增强型知名运动品牌:Proviz
2018/04/03 全球购物
美容院营销方案
2014/03/05 职场文书
2014年双拥工作总结
2014/11/21 职场文书
贷款承诺书
2015/01/20 职场文书
病假证明模板
2015/06/19 职场文书