对于“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 函数参数是传值(byVal)还是传址(byRef)?的更多相关文章

  1. delphi 函数参数传递 默认参数(传值)、var(传址)、out(输出)、const(常数)四类

    参数可以分为: 默认参数(传值).var(传址).out(输出).const(常数)四类 {默认参数是传值, 不会被改变} function MyF1(x: Integer): Integer; be ...

  2. 理解JavaScript函数参数

    前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascri ...

  3. 【C#基础概念】函数参数默认值和指定传参和方法参数

    函数参数默认值和指定传参 最近在编写代码时发现介绍C#参数默认值不能像PL/SQL那样直接设置default,网上也没有太多详细的资料,自己琢磨并试验后整理成果如下: C#允许在函数声明部分定义默认值 ...

  4. javascript 函数参数

    1.javascript函数参数的个数以及类型没有强制规定,调用时不必严格按照函数的参数或类型,函数的参数只是在调用函数的时候提供了便利,但不是必须的! 2.参数在javascript内部是用数组ar ...

  5. Js 赋值传值和引用传址

    赋值传值和引用传址 在JavaScript中基本数据类型都是赋值传值,复合数据类型都是引用传址(传地址) 基本数据类型的变量名和数据是直接存在"快速内存"(栈内存)中,而复合数据类 ...

  6. Python 函数中,参数是传值,还是传引用?

    在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(a ...

  7. 深入理解javascript函数参数与闭包(一)

    在看此文章,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为这篇文章或多或少会涉及函数基础的内容,而基础内容,我放在函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及相关知识 ...

  8. Python中参数是传值,还是传引用?

    在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(a ...

  9. js学习笔记<拷贝传值,引用传址和匿名函数>

    拷贝传值:把一个变量的值拷贝一份,传给了另外一个变量拷贝传值中,两个变量之间没有任何联系,修改其中一个一个变量的值,原来的变量不变. 例: var arr1 = ["张三",24, ...

随机推荐

  1. BoneCP主要配置参数

    二.BoneCP主要配置参数 1.jdbcUrl 设置数据库URL 2.username 设置数据库用户名 3.password 设置数据库密码 4.partitionCount 设置分区个数.这个参 ...

  2. Express中使用mongodb存储session

    express默认有队session的支持,但是是存储在内存中的. 我们可以使用mongodb来存储会话. 但是express的各个版本中对该功能的写法是不同的. Express 2.x: app.u ...

  3. CC2530之Flash映射

    标准51系列内核的逻辑空间为哈佛结构,也就是说,程序空间和地址空间是分开的.具体分为: CODE区:存放程序代码和一些常量信息,有16根地址总线,寻址范围为0x0000~0xFFFF,共计64K DA ...

  4. Java RMI 远程方法调用

    Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...

  5. .Net三维控件

    AnyCAD .Net三维建模和可视化控件为.Net 4.0开发者提供简单易用的三维建模.三维可视化和文件交换的API. 30天试用版下载: 1.  三维建模 三维建模有以下功能: 三维基本体,如点. ...

  6. C#工具介绍

    VisualStudio是微软的官方提供的.NET开发工具. 除了VisualStudio外,还有一些开源的.NET开发IDE. MonoDevelop.SharpDevelop等. 开发未必需要使用 ...

  7. 匹配一级分类和二级分类 名字和url 里面有玄机

    1:要匹配的html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// ...

  8. log tag

        Media Player MediaPlayerService     NuPlayerDecoder     NuPlayer      MediaFocusControl       Ac ...

  9. SQL允许远程访问

    1.打开sqlserver对象资源管理器 右键 方面 常规 服务器配置 RemoteAccessEnabled true RemoteDacEnabled  true 2.打开SQL SERVER管理 ...

  10. Apache 的 Rewrite 规则详细介绍

    Rewrite标志: R[=code](force redirect) 强制外部重定向 F(force URL to be forbidden) 禁用URL,返回403HTTP状态码 G(force ...