JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享


Posted in Javascript onJuly 02, 2013

对于“JavaScript 函数参数是传值(byVal)还是传址(byRef)”这个问题,普遍存在一个误区:number,string等“简单类型”是传值,Number, String, Object, Array等“复杂类型”是传址。
这样不对吗?为什么会有这样的误区?看一下这两段代码:

//造成传值假象的代码
function modifyLikeByVal(x){
  x = 1;
  console.log('x = %d', x);
}
var x = 0;
console.log('x = %d', x); // 输出 x = 0
modifyLikeByVal(x);  // 输出 x = 1
console.log('x = %d', x); // 输出 x = 0   x没变!

//造成传址假象的代码
function modifyLikeByRef(x){
  x[0] = 4;
  x[1] = 5;
  x[2] = 6;
  console.log('x = [ %s ]', x.join(', '));
}
var x = [1, 2, 3];
console.log('x = [ %s ]', x.join(', ')); // 输出 x = [ 1, 2, 3 ]
modifyLikeByRef(x);  // 输出 x = [ 4, 5, 6 ]
console.log('x = [ %s ]', x.join(', ')); // 输出 x = [ 4, 5, 6 ]   x变了!

于是,由以上代码得出结论,“简单类型”作为参数是传值(byVal)的,“复杂类型”作为参数是传址(byRef)的。

问题出在哪呢?

仔细观察两个函数,就可以发现一点:
在byVal中,是直接修改了参数x: x = 1;
而byRef中,是修改参数x的成员: x[0] = 4; x[1] = 5; x[2] = 6;

本人由此得出猜想:在JavaScript中,所有的变量或成员,都是一个指针,在修改变量或成员值的时候,其实是修改了该指针的地址。

这样上面的代码就可以得到解释了:

在“byVal”中:

global {  // 表示全局作用域,下面的表示函数作用域
  var x = 0;  // 初始化指针x并指向数字0
    fun(x) {
      x = global.x; // 传入参数global.x; fun域的x指针地址与global域的x指针地址一样指向数字0
      x = 1; // 修改fun域的x指针地址,指向数字1;
    } // fun 域结束,global域中的x指针没改变
}

在“byRef”中:
global {  // 表示全局作用域,下面的表示函数作用域
  /*
    初始化指针x并指向数组[1, 2, 3]
    其实是x的三个成员0, 1, 2,分别指向1, 2, 3;
  */
  var x = [1, 2, 3];  
    fun(x) {
      x = global.x; // 传入参数global.x; fun域的x指针地址与global域的x指针地址一样指向数组[1, 2, 3]
      /*
       在fun域中的x没有再被改变
       紧接着修改fun域中的x(也就是global.x)三个成员指针的指向
      */
      x[0] = 4;
      x[1] = 5;
      x[2] = 6;
    } // fun 域结束,global域中的x指针没改变,但其三个成员指针被改变了,于是就看到我们输出的结果
}

那这段代码怎么解释呢???
(function(a, b){
    arguments[0] = 1;
    b = 2;
    console.log(arguments, a, b);
})(-1, -2);

只能说a, b...,是arguments[0],...[n]的别名了。

如果有不对的地方,请指出来,谢谢。

如果有更好的解释,欢迎大家分享。

Javascript 相关文章推荐
jquery实现每个数字上都带进度条的幻灯片
Feb 20 Javascript
jQuery实现的动态伸缩导航菜单实例
May 07 Javascript
jQuery 全选 全部选 反选 实现代码
Aug 17 Javascript
JS获取鼠标相对位置的方法
Sep 20 Javascript
js前端解决跨域问题的8种方案(最新最全)
Nov 18 Javascript
SVG动画vivus.js库使用小结(实例代码)
Sep 14 Javascript
AngularJS遍历获取数组元素的方法示例
Nov 11 Javascript
layui table设置某一行的字体颜色方法
Sep 05 Javascript
解决layer 动态加载select 失效的问题
Sep 18 Javascript
Vue列表循环从指定下标开始的多种解决方案
Apr 08 Javascript
微信小程序 获取手机号 JavaScript解密示例代码详解
May 14 Javascript
Axios代理配置及封装响应拦截处理方式
Apr 07 Vue.js
js创建子窗口并且回传值示例代码
Jul 02 #Javascript
封装html的select标签的js操作实例
Jul 02 #Javascript
使用js获取地址栏中传递的值
Jul 02 #Javascript
jquery实现隐藏与显示动画效果/输入框字符动态递减/导航按钮切换
Jul 01 #Javascript
jquery动态增加text元素以及删除文本内容实例代码
Jul 01 #Javascript
Extjs4 Treegrid 使用心得分享(经验篇)
Jul 01 #Javascript
原生javascript兼容性测试实例
Jul 01 #Javascript
You might like
解析centos中Apache、php、mysql 默认安装路径
2013/06/25 PHP
php上传文件,创建递归目录的实例代码
2013/10/18 PHP
使用php检测用户当前使用的浏览器是否为IE浏览器
2013/12/03 PHP
PHP实现的MongoDB数据库操作类分享
2014/05/12 PHP
php json_encode与json_decode详解及实例
2016/12/13 PHP
Laravel 微信小程序后端实现用户登录的示例代码
2019/11/26 PHP
JavaScript 比较时间大小的代码
2010/04/24 Javascript
eval的两组性能测试数据
2012/08/17 Javascript
js 操作select和option常用代码整理
2012/12/13 Javascript
JavaScript 模拟类机制及私有变量的方法及思路
2013/07/10 Javascript
jQuery UI 实现email输入提示实例
2013/08/15 Javascript
jQuery实现单击按钮遮罩弹出对话框(仿天猫的删除对话框)
2014/04/10 Javascript
基于jQuery的checkbox全选问题分析
2016/11/18 Javascript
零基础轻松学JavaScript闭包
2016/12/30 Javascript
JavaScript组件开发之输入框加候选框
2017/03/10 Javascript
JavaScript之DOM_动力节点Java学院整理
2017/07/03 Javascript
vue中实现滚动加载更多的示例
2017/11/08 Javascript
JS实现简易贪吃蛇游戏
2020/08/24 Javascript
Python中的两个内置模块介绍
2015/04/05 Python
12步教你理解Python装饰器
2016/02/25 Python
python实现excel读写数据
2021/03/02 Python
Python学习小技巧总结
2018/06/10 Python
对python3中的RE(正则表达式)-详细总结
2019/07/23 Python
安装Pycharm2019以及配置anconda教程的方法步骤
2019/11/11 Python
解决Keras TensorFlow 混编中 trainable=False设置无效问题
2020/06/28 Python
美国最受欢迎的度假目的地优惠套餐:BookVIP
2018/09/27 全球购物
美国农场商店:Blain’s Farm & Fleet
2020/01/17 全球购物
两年的个人工作自我评价
2014/01/10 职场文书
上级检查欢迎词
2014/01/18 职场文书
大学生创业策划书
2014/02/02 职场文书
《走一步再走一步》教学反思
2014/02/15 职场文书
《登鹳雀楼》教学反思
2014/04/09 职场文书
团队激励口号
2014/06/06 职场文书
面试自我评价范文
2014/09/17 职场文书
曾国藩励志经典名言37句,蕴含哲理
2019/10/14 职场文书
十大最帅动漫男主 碓冰拓海上榜,第一是《灌篮高手》男主角
2022/03/18 日漫