javascript中所有函数参数都是按值传递
在看《JavaScript高级程序设计》(第三版)的时候,传递参数这一节,里面提到
ECMAScript中所有函数的参数都是按值传递的
它自己的解释是,
把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。
基本类型值的传递如同基本类型变量的复制一样,
而引用类型值的传递,则如同引用类型变量的复制一样。
我们先明白几个概念,之后再讨论。
数据类型
基本数据类型,有6种,Undefined、Null、Boolean、Number、String、Symbol
引用类型,Object、Array、Date、RegExg、Function等
数据类型介绍,可以参考JavaScript数据类型的非常6+1
内存空间
var a = 2
var b = 'abc'
var c = true
var d = {value : 1}
var e = [1, 2, 3]
定义的以上几个变量,在内存中,所占用的空间如图示意:

基础数据类型值,在栈中存储实际的值。引用数据类型值,在栈中存储引用地址值,在堆中存储实际的值。
赋值拷贝/复制
基础数据类型,赋值拷贝,拷贝实际值
var a = 1
var b = a
b = 2
console.log(a) // 1
引用类型,赋值拷贝,拷贝引用地址,浅拷贝。可以参考javascript中的浅拷贝ShallowCopy与深拷贝DeepCopy
var a = {value : 1}
var b = a
b.value = 2
console.log(a.value) // 2
举例分析
明白了以上几个概念,我们再来说说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。也就是一个赋值复制过程。我们举几个例子分析下。
1. 传递基础类型,函数中不修改参数类型
var a = 1
function func(o) {
o = 2
console.log(o)
}
func(a) // 2
console.log(a) // 1
这里的func函数,传递了一个参数o,而参数实际上是函数的局部变量。那么,我们就可以修改函数
var a = 1
function func() {
var o = a // 函数内部的参数变量,赋值函数外部的值
o = 2 // 修改内部变量的值
console.log(o)
}
func(a) // 2
console.log(a) // 1
可以得到相同的结果。他们在内存中的变化,如图示意:

从以上图中,我们能清楚的看出,变量a一直等于1,而变量o,由于赋值之后,复制了a的实际值,在内存中开辟了空间,存储在栈中。再执行func函数,修改变量o的值,只会影响其自身。
2. 传递基础类型,函数中修改类型
var a = 1
function func(o) {
o = {value : 1}
console.log(o)
}
func(a) // {value: 1}
console.log(a) // 1
同理,我们也可以修改这里的函数
var a = 1
function func() {
var o = a // 函数内部的参数变量,赋值函数外部的值
o = {value : 1} // 修改内部变量的值
console.log(o) // {value: 1}
}
func() // {value: 1}
console.log(a) // 1
内存中的变化示意图:

从以上图中,我们能清楚的看出,变量a一直等于1,而变量o,由于内部参数赋值之后,复制了a的实际值,在内存中开辟了空间,存储在栈中。再执行func函数,修改变量o的值,只会影响其自身。
3. 传递引用类型,函数中不修改类型
var a = { value : 1 }
function func(o) {
o.value = 2
console.log(o)
}
func(a) // { value : 2}
console.log(a) // {value : 2}
同理,我们也可以修改这里的函数
var a = { value : 1 }
function func() {
var o = a // 函数内部的参数变量,赋值函数外部的值
o.value = 2 // 修改内部变量的值
console.log(o) // {value: 2}
}
func() // {value: 2}
console.log(a) // {value: 2}
内存中的变化示意图:

从以上图中,我们能清楚的看出,由于变量a是引用类型,通过函数内部参数的赋值复制,传递了引用地址值,那么变量a和o会指向同一个内存对象。再执行func函数,修改变量o在堆内存中的值,并没有修改在栈中的引用地址的值。这样,由于变量o和变量a使用的是同一个引用地址,也就是同一个堆内存中的值,那么变量a的值,也就会随着变量o的变化而变化了。
4. 传递引用类型,函数中修改类型
var a = {value : 1 }
function func(o) {
o = 2
console.log(o)
}
func(a) // 2
console.log(a) // { value : 1}
接下来,我们也可以修改这里的函数
var a = { value : 1 }
function func() {
var o = a // 函数内部的参数变量,赋值函数外部的值
o = 2 // 修改内部变量的值
console.log(o) // 2
}
func() // 2
console.log(a) // {value: 1}
内存中的变化示意图:

由于变量a是引用类型,通过函数内部参数的赋值复制,传递了引用地址值,那么变量a和o会指向同一个内存对象。再执行func函数时,改变了变量o的数据类型,变成了基础数据类型,也就切断了引用。这样,变量a和o就没有关系了。
总结
JavaScript中所有函数参数都是按值传递的。基本类型值,传递的是实际值,引用类型,传递的是引用地址值。
参考
javascript中所有函数参数都是按值传递的更多相关文章
- JavaScript中Function函数与Object对象的关系
函数对象和其他内部对象的关系 除了函数对象,还有很多内部对象,比如:Object.Array.Date.RegExp.Math.Error.这些名称实际上表示一个 类型,可以通过new操作符返回一个对 ...
- Javascript中的函数(Function)与对象(Object)的关系
今天我们来尝试理解Function和Object.因为这个里面有些人前期可能会搞糊涂.他们之间到底是什么关系.当然也不除外当初的我. 注意:官方定义: 在Javascript中,每一个函数实际上都是一 ...
- javascript中所有函数的参数都是按值传递的
[javascript中所有函数的参数都是按值传递的] 参考:http://www.jb51.net/article/89297.htm
- 《JavaScript高级程序设计》读书笔记--ECMAScript中所有函数的参数都是按值传递的
ECMAScript中所有函数的参数都是按值传递的.也就是说把函数外部的值复制给函数内部的参数(内部参数的值的修改不影响实参的值). 基本类型变量的复制: 基本类型变量的复制,仅仅是值复制,num1和 ...
- javascript中的所有内容都是一个对象:字符串、值、数组、函数…
javascript中的所有内容都是一个对象:字符串.值.数组.函数…此外,javascript允许自定义对象.javascript对象JavaScript提供多个内置对象,如字符串.日期.数组等.对 ...
- JS对象 JavaScript 中的所有事物都是对象,如:字符串、数值、数组、函数等,每个对象带有属性和方法。
什么是对象 JavaScript 中的所有事物都是对象,如:字符串.数值.数组.函数等,每个对象带有属性和方法. 对象的属性:反映该对象某些特定的性质的,如:字符串的长度.图像的长宽等: 对象的方法: ...
- JavaScript中Eval()函数的作用
这一周感觉没什么写的,不过在研究dwz源码的时候有一个eval()的方法不是很了解,分享出来一起学习 -->首先来个最简单的理解 eval可以将字符串生成语句执行,和SQL的exec()类似. ...
- Javascript中的函数
Javascript中的函数 1.什么是函数 函数是被命名的,独立的,完成特定功能的代码段.其可能给调用它的程序返回值,我们把这个代码段就称之为"函数". 被命名的:函数大部分都是 ...
- 浅析 JavaScript 中的 函数 currying 柯里化
原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...
随机推荐
- Flex布局【弹性布局】学习
先让我们看看在原来的学习中遇到的问题 之前在软件工程的大作业中,自己从零开始学习如何开发一个网站,从页面,到后台,当然数据库是大二的必修课 在学习如何编写一个静态页面的时候,完全是自学,自己摸索,所以 ...
- Bellman-Ford&&SPFA
我们前文说过,有关最短路径除了Floyed算法之外,还有许多更加好的方法.这里讲一下有关 Bellman-Ford和SPFA的知识 Bellman-Ford:复杂度O(VE) 有关Bellman-Fo ...
- Exp5 MSF基础应用
一.实践内容 1.主动攻击实践 [1]MS08-067 MS08-067 漏洞是2008 年年底爆出的一个特大漏洞,存在于当时的所有微软系统,杀伤力超强.其原理是攻击者利用受害主机默认开放的SMB 服 ...
- Exp4 恶意代码分析
一.原理与实践说明 1. 实践目标 1.1 监控你自己系统的运行状态,看有没有可疑的程序在运行. 1.2 分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysin ...
- Apache Hadoop 2.9.2 的快照管理
Apache Hadoop 2.9.2 的快照管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 快照相当于对目录做一个备份.并不会立即复制所有文件,而是指向同一个文件.当写入发生 ...
- 【sql server】“因为数据库正在使用,所以无法获得对数据库的独占访问权” 解决方案汇总
#事故现场: 在尝试还原数据库时,出现如下错误: #方案一:设置数据库在单用户模式下工作: 1.数据库上右键“属性”: 2.“选项”->“限制访问”,选择“SINGLE_USER” 3.还原数据 ...
- 责任链模式-Chain of Responsibility(Java实现), 例1
责任链模式-Chain of Responsibility, 例1 在这种模式中,通常每个接收者都包含对另一个接收者的引用.如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推. ...
- #1 macos和windows下对多Python环境配置的记录
为啥会发现环节配置的问题 因为scrapy的setting前期走弯路的时候,碰到了修改了Windows下的Python中的scrapy的默认setting,但是我电脑上还有anaconda,而且我是使 ...
- C#匿名对象(转JSON)
多类型匿名对象 var result = new { pages = , users = new System.Collections.ArrayList { ,name="}, ,name ...
- 在mysql 5.7中,创建表的字段名中包含双引号的时候,执行会报错
解决办法,添加 SET SESSION SQL_MODE=ANSI_QUOTES;