浅析js的函数的按值传递参数
js的函数传参的方式是按值传递,正常情况下,改变函数参数的值,并不会对函数外部的变量造成影响。例如:
'use strict';
var list = [1, 2, 3];
list.forEach(function(item) {
item ++;
});
console.log(list); // [ 1, 2, 3 ]
这是因为js的函数在接收参数时,会生成一个副本变量,该副本变量等于参数的值,可以分析js这样运行的:
'use strict';
var list = [1, 2, 3];
list.forEach(function(item, i) {
// 第一个item是副本,第二个item是数组元素list[i]
var item = item;
// 副本item++
item ++;
// 打印的是副本的值
console.log(item); // 2, 3, 4
});
// 原数组不会改变
console.log(list); // [ 1, 2, 3 ]
但是当函数的参数传递的是一个对象呢?
'use strict';
var list = [{a: , b: }];
list.forEach(function(item) {
item.a ++;
});
console.log(list); // [ { a: 2, b: 2 } ]
发现函数内部居然改变了函数外部变量的值,那这又是为什么呢?
我们来分析js是如何运行这段代码的
'use strict';
var list = [{a: 1, b: 2}];
list.forEach(function(item, i) {
// 第一个item是副本,第二个item是数组元素list[i]
var item = item;
// 此时item和list[i]指向的是同一地址,故两者完全一样
console.log(item === list[i]); // true
// 此时item.a++ 亦即 list[i].a++
item.a ++;
// list[i]的值已经改变
console.log(list[i]); // { a: 2, b: 2 }
});
console.log(list); // [ { a: 2, b: 2 } ]
那么为什么会产生这种情况呢?
由于js中对象属于引用类型,var item = item 这一步相当于把 list[i] 的地址赋值给了item,他们两个指向的都是原对象的地址,所以通过其中的一个去修改值时其实是修改他们指向的那个对象。例子中通过 item.a++ 方法改变了原对象的值,因此最后应该输出 [ { a: 2, b: 2 } ]。
浅析js的函数的按值传递参数的更多相关文章
- js 获取函数的所有参数名
具体思路: 利用Function.toString()方法,获取到函数的源码,再利用正则匹配获取到参数名字. 实现代码(代码基于ES6): // 获取函数的参数名 function getParame ...
- js 以函数名作为参数动态执行 函数
function myFunc() { console.log(11111); } test("myFunc"); function test(funcName) { if(typ ...
- js 事件函数中的参数带换行符或换行标签都不能起作用的解决方法
把问题参数值赋给标签的属性data-value,通过属性值获取参数值.
- 【js】函数问题
一.函数重载问题: 由于js的函数传入的参数当做arguments对象(和数组类似,但不是Array的实例),传入的参数类型和数量没有限制,没有函数签名,所以如果要实现重载功能 的话,只能是不够完美得 ...
- JS:函数多个参数默认值指定
函数有一个参数时,以往这样定义(参数为p1): function mfun(p1){ … } 当需要为p1设定一个默认值时 function mfun(p1){ if(p1===undefined) ...
- js调用函数时传入的参数个数与函数定义时的参数个数不符时的操作
在js中函数没有重载的概念,如果声明了多个重名的函数,不管函数的形参个数是否一样,只有最有一个有效,其他的函数声明都是无效的.比如说声明了两个函数fn(),第一次声明时没有形参,第二次声明时形参有两个 ...
- JS中函数参数和函数返回值的理解
函数本质就是功能的集合 JS中函数是对象,因此,函数名实际上仅仅是一个指向函数对象的指针,不会与某个函数绑定,所以,JS中没有重载(重载就是通过传递不同类型的参数,使两个相同函数名的函数执行不同的功能 ...
- js 四舍五入函数 toFixed(),里面的参数 就是保留小数的位数。
js 四舍五入函数 toFixed(),里面的参数 就是保留小数的位数. <script language="javascript"> document.write(& ...
- 关于js 中函数的参数
var a = 100; function test(a){ a++; //a(形参)是局部变量 console.log(a); } test(a); console.log(a); //结果是 10 ...
随机推荐
- Codeforces_766_C_(dp)
C. Mahmoud and a Message time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- 打造个人的vimIDE
环境说明 系统版本:centos7.Ubuntu16 vim版本:7.4 安装git工具 整体说明:本文的vim配置是针对Linux的单个系统用户,python的自动补全使用的是 jedi-vim 插 ...
- HDU多校Round 3
Solved:4 rank:268 C. Dynamic Graph Matching 状压DP一下 #include <stdio.h> #include <algorithm& ...
- wpf 自定义单选按钮 RadioButton
新建RadioButtonEx.cs public class RadioButtonEx : RadioButton { public Geometry SelectIcon { get { ret ...
- JPA API与注解
一.JPA API Persistence 类:用于获取 EntityManagerFactory 实例,该类含有静态方法 createEntityManagerFactory. //persiste ...
- Android中ProgressDialog自动消失
主要函数部分代码: final ProgressDialog proDialog = android.app.ProgressDialog .show(MainActivity.this, " ...
- C#读取文件-古文观止(总结一下)
1,读取单个文件 //读取一个文本文件 private void buttonRead_Click(object sender, EventArgs e) { String path = Enviro ...
- poj - 3254 - Corn Fields (状态压缩)
poj - 3254 - Corn Fields (状态压缩)超详细 参考了 @外出散步 的博客,在此基础上增加了说明 题意: 农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的( ...
- [bzoj1820][JSOI2010][Express Service 快递服务] (动态规划)
Description 「飞奔」快递公司成立之后,已经分别与市内许多中小企业公司签订邮件收送服务契约.由于有些公司是在同一栋大楼内,所以「飞奔」公司收件的地点(收件点)最多只有m点 (1, 2, …, ...
- log 框架 之间的关系
日志框架分为两大部分 一部分是日志框架的抽象层,一部分是日志框架的具体实现 slf4j: 日志框架的抽象层 log4j,logback 日志框架的具体实现 如上图所示: slf4j的具体实现是:slf ...