浅析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 ...
随机推荐
- HDU_6017_Girls love 233_(dp)(记忆化搜索)
Girls Love 233 Accepts: 30 Submissions: 218 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- form表单传输多余参数
1.使用post提交表单,同时在form的action属性后添加“?参数=参数值”,经验证,可行,但是在浏览器中看不到该参数在form参数中,如下图: 上图未出现courseId属性,form代码如下 ...
- css--小白入门篇6(终)
一.相对定位 定位有三种,分别是相对定位.绝对定位.固定定位. 相对定位: 1 position:relative; 绝对定位: 1 position:absolute; 固定定位: 1 positi ...
- KMP瞎扯一下
什么是KMP KMP俗称看毛片算法,是高效寻找匹配字串的一个算法 百度百科 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为 ...
- TestNG多线程测试-用xml文件实现
MultiThreadOnXml类: package com.janson.multiThread; import org.testng.annotations.Test; public class ...
- 集合:ListIterator
why ? when ? how ? what ? Java 集合框架图 有了 Iterator 为什么还要有 ListIterator 呢? Iterator 遍历的时候如果你想修改集合中的元素怎么 ...
- 使用yolo3模型训练自己的数据集
使用yolo3模型训练自己的数据集 本项目地址:https://github.com/Cw-zero/Retrain-yolo3 一.运行环境 1. Ubuntu16.04. 2. TensorFlo ...
- Sturts2中Action的搜索顺序
http://localhost:8080/ProjectName/path1/path2/path3/XX.action 首先会判断以/path1/paht2/path3为namespace的pac ...
- python基础面试题30问(附带答案)
1. 闭包 定义:闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)(想想Erlang的外层函数传入一个参数a, 内层函数依旧传入一个参数b, 内层函数使用a和b, 最后 ...
- 洛谷 2146 [NOI2015]软件包管理器
[题解] 每个软件只依赖另一个软件,且依赖关系不构成环,那么很容易想到这是树形结构. 我们用1表示以安装,用0表示未安装或已卸载:那么安装一个软件,就是把它到树根的路径上所有的点都改为1:卸载一个软件 ...