JavaScript之参数传递

170 阅读2分钟

ECMAScript中所有函数的参数都是按值传递的。

理解这句话,只要弄清楚一点:保存对象的变量,它里面装的值是这个对象在堆内存中的地址。

1.数据类型

javascript的数据类型可分为两类:

  • 原始数据类型:比如Undefined,Null,Boolean,Number,String。它是存储在栈(stack)中的简单数据段,它的值直接存储在变量访问的位置,因此可以直接得到变量的值。

  • 引用类型:也就是对象,比如Object,Array,Function,Date。它是存储在堆(heap)中的对象,存储的值是一个指针,指向对象存储的内存地址

javascript不允许直接访问保存在堆内存中的对象,访问时先得到这个对象在堆内存中的地址,然后按照这个地址获得对象的值,即为按引用访问

2.复制变量

  • 原始值:将一个保存原始值的变量复制给另一个变量时,会将原始值的副本赋值给新变量,此后两个变量完全独立,他们只是拥有相同的value。

  • 引用值:将一个保存着对象内存地址的变量赋值给另一个对象时,会把这个内存地址赋值给新对象,此后他们指向堆内存中的同一个对象,任何一个改变都会影响另一个。

3.参数传递

可以将参数传递的过程,理解为把实参复制给形参的过程。

  • 原始值:只是把变量里的值传递给参数,之后参数和这个变量相互独立
  • 引用值:传递的值是对象的内存地址,函数内部对参数修改会影响外部的变量

例如

var value = 1; //原始值
function foo(v) {
    v = 2;
    console.log(v); //2
}
foo(value);
console.log(value) // 1

注意: 引用值的变量把它的值赋值给了参数,让参数也指向原对象。

但是如果在函数内部,给参数赋值另一个对象,这个参数会更改它的值指向新对象的地址,此时原对象仍然指向原对象的地址,这时候他们是相互独立的。

如果参数只是改变对象内部的属性的话,他们共同指向的对象也会被修改。

例如:

var obj1 = { 
  value:'111' 
}; 
var obj2 = { 
  value:'222' 
}; 
function changeStuff(obj){ 
   obj.value = '333'; //obj指向obj1,改变内部属性
   obj = obj2; //赋值新对象,obj指向obj2
   return obj.value; 
} 
var foo = changeStuff(obj1); 
console.log(foo);// '222'
console.log(obj1.value);//'333'