揭秘ECMAScript参数值传递与“引用”传递

揭秘ECMAScript参数值传递与“引用”传递

  js红皮书中文版中(P66)说:“ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数”,然众所周知,js中有object数据类型,虽然其他高级语言函数参数传递分为值传递和引用传递,但是js中object作为参数是以值传递的(P71)。

1. 值传递

function addNum(num)
{ 
 num+=10; 
 return num; 
} 
var num=10; 
var result=addNum(num); 
console.log(num); // 10
console.log(result); // 20

  num是值类型,函数传参时将此值复制一份传递给函数,所以在函数执行之后,num本身的值并没有被改变,函数中被改变的值仅仅是一个副本而已。

2.object值传递1

function setName(obj)
{ 
  obj.name="sunshine"; 
} 
var web=new Object(); 
web.name="csxiaoyao";
setName(web); 
console.log(web.name); // sunshine

  web对象是引用类型,函数传参时参数传递给setName后被复制给obj,在这个函数内部,obj和web引用的是同一个对象,即:值传递。此处obj和web指向同一个对象,而且是全局对象,所以函数内修改,外部也有反映。

【错误理解】:之前错误地认为局部域中修改对象会在全局域中体现即为引用传递,这个理解是错误的,引用传递指传递的是对象的内存地址,在函数中修改属性的对象就是函数外面创建的对象本身,与此处不同。见下例。

3.object值传递2

function setName(obj)
{ 
  obj.name="sunshine"; 
  obj=new Object(); 
  obj.name="csxiaoyao"; 
} 
var web=new Object(); 
setName(web); 
console.log(web.name); // sunshine

  在函数中又创建一个新的对象,此时obj指向的并不是函数外面创建的对象,所以外面对象name属性值不会被改变,由此可见参数传递为值传递。

如果为引用传递,在函数外创建一个对象,并将对象的引用赋值给变量web,web中存储的是对象在内存中的存储地址,函数传参时传递的是在函数外面创建的对象的地址,那么新建对象应该会覆盖原来的对象。

总结

  js的参数传递与其他高级语言有所不同,只有值传递,即使传递的是对象。可以把ECMAScript函数的参数想象成局部变量,这个局部变量每次在函数进入时复制一份,函数执行完毕后立即销毁。

你可能感兴趣的:(javascript)