前言
看到这个文章标题可能会感觉有那么一丝丝奇怪,参数?按照什么传递?这里其实说的是当调用函数时,传入的的实参到底是按照什么规则传递的,你也许会脱口而出,是什么值就按照什么类型传递白,还能有什么特殊的吗?我之前也是这么想的,直到遇到了下面的这些例子
简单的基本类型传递
var value = 2;
function test(value){
value = 4;
console.log(value) //4
}
test(value)
console.log(value) //2
这就是我们平常印象中的那种实参的传递形式,感觉一切的应该都是这样的,那么接着看下面的例子
复杂的数据类型传递(对象)
var dog = {
color:'yellow'
}
function test(obj){
obj.color = 'white'
console.log(obj.color)
}
test(dog)
console.log(dog.color)
结果如下:
哎呦,怎么会都是white呢?传进函数内部的参数不都是应该独立的吗,怎么会影响到外面的对象呢,难道传递进去的实参是一个引用的地址?从上面的两段代码我们可以发现,基本类型的是时候传递进函数的实参是以值的应式传递的,复杂类型的时候(对象)是传递进去的一个引用地址,但真的是这样吗?再来看一段代码
var dog = {
color:'yellow'
}
function test(obj){
obj = 1
console.log(obj)
}
test(dog)
console.log(dog.color)
结果如下:
哎呦,结果怎么又变了?上面的第二段代码不是说传递复杂的类型就是传递的引用地址吗?其实这是没有问题的,在js中其实所有函数实参的传递都可以理解为值的传递。这里之所以出现这样的问题是因为他们在内存中的存储不一样(个人理解,不喜勿喷)。
- 第一段代码中基本的数据类型是在栈中,参数传递的时候传递的参数的副本,所以在函数中修改不会影响到外面的参数。
- 第二段代码中实参是一个对象,但传递的其实是一个引用地址,因为引用数据类型是存储在栈中。这时候dog和obj其实指向的是同一块地址,那在函数中修改obj.color当然会影响到函数外边的dog了。
- 第三段代码其实也是传递的引用地址,和第二段的不同点是,在函数中直接改变了obj的指向,这时候obj和dog指向的就不是一块地址了,所以没有影响。
总结
其实在js中所有值的传递都是值的传递,因为传递的引用地址也是一种值(感觉挺难理解的,哈哈)