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

对于“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]的别名了。

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

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

时间: 2024-08-02 19:46:27

JavaScript 函数参数是传值(byVal)还是传址(byRef) 分享_javascript技巧的相关文章

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

对于"JavaScript 函数参数是传值(byVal)还是传址(byRef)"这个问题,普遍存在一个误区:number,string等"简单类型"是传值,Number, String, Object, Array等"复杂类型"是传址. 这样不对吗?为什么会有这样的误区?看一下这两段代码: 复制代码 代码如下: //造成传值假象的代码 function modifyLikeByVal(x){   x = 1;   console.log('x =

javascript中的变量是传值还是传址的?_javascript技巧

这个标题念起来有点拗口,但却是理解数据结构的关键.标题中的4个术语,对应的英文分别是:shallow copy(注意,不是shadow copy).deep copy.pass by value.pass by reference(或pass by address).传址和传引用是一回事. 一门编程语言的核心是数据结构,粗略来讲,可以把数据结构分成不可变类型(immutable)和可变类型(mutable).为什么这么分呢?这涉及到内存分配问题.对于不可变类型,只要分配有限的内存空间即可,而对于

javascript正则表达式参数/g与/i及/gi的使用指南_javascript技巧

regularexpression=/pattern/[switch] 这个switch就有三种值 g: 全局匹配 i: 忽略大小写 gi: 全局匹配 + 忽略大小写 JScript 语言参考 -------------------------------------------------------------------------------- 后向引用 正则表达式一个最重要的特性就是将匹配成功的模式的某部分进行存储供以后使用这一能力.请回想一下,对一个正则表达式模式或部分模式两边添加圆

使用CSS+JavaScript或纯js实现半透明遮罩效果的实例分享_javascript技巧

CSS+JavaScript实现原理: 创建一个满屏的div,使用绝对定位,这样的话它就可以脱离文档流,对其他的元素不会产生影响,并且将其设置为半透明状态,当然这个透明度可以随便调的,同时创建一个login元素,它也使用绝对定位,并将其z-index属性值大于面屏的div,这个时候它就不会被满屏div遮盖.在默认状态下这两个div的display属性值是none.当点击相应的按钮可以更改他们的display属性值. <!DOCTYPE html> <html> <head&g

javascript中RegExp保留小数点后几位数的方法分享_javascript技巧

复制代码 代码如下:     <script type="text/javascript">var db = "0.123456789";//原数值var num = 5;//小数点后位数var re = new RegExp("\d+\.\d{" + num + "}","gm"); alert(db.match(re));</script></td>   </t

JavaScript实现防止网页被嵌入Frame框架的代码分享_javascript技巧

最近,国内开始流行另一种流氓行为:使用框架(Frame),将你的网页嵌入它的网页中. 比如,有一家网站号称自己是"口碑聚合门户",提供全国各个网上论坛的精华内容.但是,其实它就是用框架抓取他人的网页,然后在上面加上自己的广告和站标,这同盗版书商有何不同?! 防止方法,在 复制代码 代码如下: </body> 之前加入这段代码: 复制代码 代码如下: <script type="text/javascript">  if ( top.locat

深入理解JavaScript函数参数(推荐)_javascript技巧

前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascript中的函数定义并未指定函数形参的类型,函数调用也未对传入的实参值做任何类型检查.实际上,javascript函数调用甚至不检查传入形参的个数 function add(x){ return x+1; } console.log(add(1));//2 console.log(add('1'));/

JavaScript函数参数使用带参数名的方式赋值传入的方法

 这篇文章主要介绍了JavaScript函数参数使用带参数名的方式赋值传入的方法,实例分析了javascript函数传递参数的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下     本文实例讲述了JavaScript函数参数使用带参数名的方式赋值传入的方法.分享给大家供大家参考.具体分析如下: 这里其实就是在给函数传递参数的时候,可以使用 参数名:参数值的方式传递,这样不会传递错.不过下面的代码是通过字典来实现的,不像python原封就支持这样的方法 ? 1 2 3 4 function

JavaScript函数参数使用带参数名的方式赋值传入的方法_javascript技巧

本文实例讲述了JavaScript函数参数使用带参数名的方式赋值传入的方法.分享给大家供大家参考.具体分析如下: 这里其实就是在给函数传递参数的时候,可以使用 参数名:参数值的方式传递,这样不会传递错.不过下面的代码是通过字典来实现的,不像python原封就支持这样的方法 function foo({ name:name, project:project}) { Print( project ); Print( name ); } 调用方法 foo({ name:'soubok', projec