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 相关文章推荐
JavaScript跨域方法汇总
Oct 16 Javascript
jQuery插件bxSlider实现响应式焦点图
Apr 12 Javascript
jQuery Mobile弹出窗、弹出层知识汇总
Jan 05 Javascript
js实现首屏延迟加载实现方法 js实现多屏单张图片延迟加载效果
Jul 17 Javascript
AngularJs 延时器、计时器实例代码
Sep 16 Javascript
jquery+ajaxform+springboot控件实现数据更新功能
Jan 22 jQuery
vue自定v-model实现表单数据双向绑定问题
Sep 03 Javascript
浅谈JS的原型和继承
May 08 Javascript
jQuery控制input只能输入数字和两位小数的方法
May 16 jQuery
swiper实现异形轮播效果
Nov 28 Javascript
vue中watch和computed为什么能监听到数据的改变以及不同之处
Dec 27 Javascript
关于vue属性使用和不使用冒号的区别说明
Oct 22 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
一个MYSQL操作类
2006/11/16 PHP
PHP取二进制文件头快速判断文件类型的实现代码
2013/08/05 PHP
php数组删除元素示例
2014/03/21 PHP
ThinkPHP中where()使用方法详解
2016/04/19 PHP
ThinkPHP整合datatables实现服务端分页的示例代码
2018/02/10 PHP
php json转换相关知识(小结)
2018/12/21 PHP
javascript web页面刷新的方法收集
2009/07/02 Javascript
根据经纬度计算地球上两点之间的距离js实现代码
2013/03/05 Javascript
js 得到文件后缀(通过正则实现)
2013/07/08 Javascript
js操作滚动条事件实例
2015/01/29 Javascript
javascript实现复选框超过限制即弹出警告框的方法
2015/02/25 Javascript
JavaScript设置表单上传时文件个数的方法
2015/08/11 Javascript
基于jQuery实现返回顶部实例代码
2016/01/01 Javascript
jQuery操作Table技巧大汇总
2016/01/23 Javascript
jQuery控制frames及frame页面JS的方法
2016/03/08 Javascript
JavaScript Ajax编程 应用篇
2016/07/02 Javascript
Vue-router 类似Vuex实现组件化开发的示例
2017/09/15 Javascript
node中使用log4js4.x版本记录日志的方法
2019/08/20 Javascript
javascript+css实现俄罗斯方块小游戏
2020/06/28 Javascript
[34:39]Secret vs VG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
python三元运算符实现方法
2013/12/17 Python
使用Python的Flask框架实现视频的流媒体传输
2015/03/31 Python
Python while、for、生成器、列表推导等语句的执行效率测试
2015/06/03 Python
详解python列表(list)的使用技巧及高级操作
2019/08/15 Python
如何更改 pandas dataframe 中两列的位置
2019/12/27 Python
python pprint模块中print()和pprint()两者的区别
2020/02/10 Python
python报错: 'list' object has no attribute 'shape'的解决
2020/07/15 Python
ECCO爱步官方旗舰店:丹麦鞋履品牌
2018/01/02 全球购物
华为慧通笔试题
2016/04/22 面试题
求职信格式范本
2013/11/15 职场文书
语文教育专业推荐信范文
2013/11/25 职场文书
单位工作证明格式模板
2014/10/04 职场文书
人事专员岗位职责
2015/02/03 职场文书
python 使用tkinter与messagebox写界面和弹窗
2022/03/20 Python
MSSQL基本语法操作
2022/04/11 SQL Server
el-table-column 内容不自动换行的解决方法
2022/08/14 Vue.js