JavaScript 函数参数是传值(byVal)还是传址(byRef)?
对于“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)?的更多相关文章
- delphi 函数参数传递 默认参数(传值)、var(传址)、out(输出)、const(常数)四类
参数可以分为: 默认参数(传值).var(传址).out(输出).const(常数)四类 {默认参数是传值, 不会被改变} function MyF1(x: Integer): Integer; be ...
- 理解JavaScript函数参数
前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型,甚至可以不传参数. arguments javascri ...
- 【C#基础概念】函数参数默认值和指定传参和方法参数
函数参数默认值和指定传参 最近在编写代码时发现介绍C#参数默认值不能像PL/SQL那样直接设置default,网上也没有太多详细的资料,自己琢磨并试验后整理成果如下: C#允许在函数声明部分定义默认值 ...
- javascript 函数参数
1.javascript函数参数的个数以及类型没有强制规定,调用时不必严格按照函数的参数或类型,函数的参数只是在调用函数的时候提供了便利,但不是必须的! 2.参数在javascript内部是用数组ar ...
- Js 赋值传值和引用传址
赋值传值和引用传址 在JavaScript中基本数据类型都是赋值传值,复合数据类型都是引用传址(传地址) 基本数据类型的变量名和数据是直接存在"快速内存"(栈内存)中,而复合数据类 ...
- Python 函数中,参数是传值,还是传引用?
在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(a ...
- 深入理解javascript函数参数与闭包(一)
在看此文章,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为这篇文章或多或少会涉及函数基础的内容,而基础内容,我放在函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及相关知识 ...
- Python中参数是传值,还是传引用?
在 C/C++ 中,传值和传引用是函数参数传递的两种方式,在Python中参数是如何传递的?回答这个问题前,不如先来看两段代码. 代码段1: def foo(arg): arg = 2 print(a ...
- js学习笔记<拷贝传值,引用传址和匿名函数>
拷贝传值:把一个变量的值拷贝一份,传给了另外一个变量拷贝传值中,两个变量之间没有任何联系,修改其中一个一个变量的值,原来的变量不变. 例: var arr1 = ["张三",24, ...
随机推荐
- BoneCP主要配置参数
二.BoneCP主要配置参数 1.jdbcUrl 设置数据库URL 2.username 设置数据库用户名 3.password 设置数据库密码 4.partitionCount 设置分区个数.这个参 ...
- Express中使用mongodb存储session
express默认有队session的支持,但是是存储在内存中的. 我们可以使用mongodb来存储会话. 但是express的各个版本中对该功能的写法是不同的. Express 2.x: app.u ...
- CC2530之Flash映射
标准51系列内核的逻辑空间为哈佛结构,也就是说,程序空间和地址空间是分开的.具体分为: CODE区:存放程序代码和一些常量信息,有16根地址总线,寻址范围为0x0000~0xFFFF,共计64K DA ...
- Java RMI 远程方法调用
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- .Net三维控件
AnyCAD .Net三维建模和可视化控件为.Net 4.0开发者提供简单易用的三维建模.三维可视化和文件交换的API. 30天试用版下载: 1. 三维建模 三维建模有以下功能: 三维基本体,如点. ...
- C#工具介绍
VisualStudio是微软的官方提供的.NET开发工具. 除了VisualStudio外,还有一些开源的.NET开发IDE. MonoDevelop.SharpDevelop等. 开发未必需要使用 ...
- 匹配一级分类和二级分类 名字和url 里面有玄机
1:要匹配的html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http:// ...
- log tag
Media Player MediaPlayerService NuPlayerDecoder NuPlayer MediaFocusControl Ac ...
- SQL允许远程访问
1.打开sqlserver对象资源管理器 右键 方面 常规 服务器配置 RemoteAccessEnabled true RemoteDacEnabled true 2.打开SQL SERVER管理 ...
- Apache 的 Rewrite 规则详细介绍
Rewrite标志: R[=code](force redirect) 强制外部重定向 F(force URL to be forbidden) 禁用URL,返回403HTTP状态码 G(force ...