在看《JavaScript高级程序设计》(第三版)的时候,传递参数这一节,里面提到javascript
ECMAScript中全部函数的参数都是按值传递的html
它本身的解释是,java
把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另外一个变量同样。
基本类型值的传递如同基本类型变量的复制同样,
而引用类型值的传递,则如同引用类型变量的复制同样。git
咱们先明白几个概念,以后再讨论。github
基本数据类型,有6种,Undefined、Null、Boolean、Number、String、Symbol函数
引用类型,Object、Array、Date、RegExg、Function等设计
数据类型介绍,能够参考JavaScript数据类型的很是6+1code
var a = 2 var b = 'abc' var c = true var d = {value : 1} var e = [1, 2, 3]
定义的以上几个变量,在内存中,所占用的空间如图示意:htm
基础数据类型值,在栈中存储实际的值。引用数据类型值,在栈中存储引用地址值,在堆中存储实际的值。对象
基础数据类型,赋值拷贝,拷贝实际值
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
明白了以上几个概念,咱们再来讲说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另外一个变量同样。也就是一个赋值复制过程。咱们举几个例子分析下。
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
的值,只会影响其自身。
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
的值,只会影响其自身。
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
的变化而变化了。
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中全部函数参数都是按值传递的。基本类型值,传递的是实际值,引用类型,传递的是引用地址值。