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 相关文章推荐
Json序列化和反序列化方法解析
Dec 19 Javascript
JavaScript中的值类型转换介绍
Dec 31 Javascript
javascript正则表达式基础知识入门
Apr 20 Javascript
jQuery的css() 方法使用指南
May 03 Javascript
D3.js实现柱状图的方法详解
Sep 21 Javascript
JavaScript实现弹出广告功能
Mar 30 Javascript
基于 Vue 实现一个酷炫的 menu插件
Nov 14 Javascript
js登录滑动验证的实现(不滑动无法登陆)
Jan 03 Javascript
Angular入口组件(entry component)与声明式组件的区别详解
Apr 09 Javascript
javascript系统时间设置操作示例
Jun 17 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
Sep 06 Javascript
在vue中实现某一些路由页面隐藏导航栏的功能操作
Sep 21 Javascript
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
php中使用gd库实现下载网页中所有图片
2015/05/12 PHP
js chrome浏览器判断代码
2010/03/28 Javascript
js 限制数字 js限制输入实现代码
2012/12/04 Javascript
javascript实现五星评价代码(源码下载)
2015/08/11 Javascript
js实现完美兼容各大浏览器的人民币大小写相互转换
2015/10/29 Javascript
AngularJS教程之环境设置
2016/08/16 Javascript
js 输入框 正则表达式(菜鸟必看教程)
2017/02/19 Javascript
JS 60秒后重新发送验证码的实例讲解
2017/07/26 Javascript
简述jQuery Easyui一些用法
2017/08/01 jQuery
浅谈vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
2017/12/07 Javascript
基于express中路由规则及获取请求参数的方法
2018/03/12 Javascript
解析Json字符串的三种方法日常常用
2018/05/02 Javascript
jQuery 判断元素是否存在然后按需加载内容的实现代码
2020/01/16 jQuery
JS使用Chrome浏览器实现调试线上代码
2020/07/23 Javascript
Python 文件处理注意事项总结
2017/04/10 Python
Python实现随机选择元素功能
2017/09/14 Python
python3 发送任意文件邮件的实例
2018/01/23 Python
Python中elasticsearch插入和更新数据的实现方法
2018/04/01 Python
python3.5 email实现发送邮件功能
2018/05/22 Python
python开发游戏的前期准备
2019/05/05 Python
python re.sub()替换正则的匹配内容方法
2019/07/22 Python
Pytorch训练过程出现nan的解决方式
2020/01/02 Python
python 实现逻辑回归
2020/12/30 Python
Ajax和javascript的区别
2013/07/20 面试题
护理毕业生自荐信范文
2013/12/22 职场文书
互联网创业计划书的书写步骤
2014/01/28 职场文书
小学生演讲稿大全
2014/04/25 职场文书
毕业生求职信范文
2014/06/29 职场文书
推普周国旗下讲话稿
2014/09/21 职场文书
镇班子对照检查材料思想汇报
2014/09/24 职场文书
优秀教师个人材料
2014/12/15 职场文书
Python3 类型标注支持操作
2021/06/02 Python
python not运算符的实例用法
2021/06/30 Python
简单且有用的Python数据分析和机器学习代码
2021/07/02 Python
带你了解Java中的ForkJoin
2022/04/28 Java/Android
Win11怎么解除儿童账号限制?Win11解除微软儿童账号限制方法
2022/07/07 数码科技