函数的参数传递

函数的参数传递

传值还是传引用?

function changeStuff(num, obj1, obj2)
{
    num = num * 10;
    obj1.item = "changed";
    obj2 = {item: "changed"};
}
 
var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num);   // 10
console.log(obj1.item);    // changed
console.log(obj2.item);    // unchanged

传值

函数内的num, obj1, obj2都将是一份新的内存,与调用函数之前定义的三个变量毫无关系。函数内无论怎么修改这三个参数,外部定义的三个变量的值始终不变

传值的意思就是:传内存拷贝。

传引用

函数内的num, obj1, obj2都分别指向一块内存,该内存就是调用函数之前定义的三个变量时创建的内存。函数内对这三个参数所做的任何改动,都将反映到外部定义的三个变量上。

传引用的意思就是:传内存指针。

从上面的代码可以看出,JavaScript中函数参数的传递方式既不是传值,也不是传引用,而是叫call-by-sharing。

Call-by-sharing

它的意思是:传引用的拷贝。

changeStuff()中的num, obj1, obj2都是一个引用
他们的内容是某块内存的地址
这个地址的值来自于外部定义的三块内存,是那三块内存地址的一份拷贝
同时,在函数内部这三个参数的值是可以直接被修改的,可以指向其他对象(由于JavaScript中没有指针或引用运算符,只能直接修改)
因此,我们从内存和引用的角度再来看看changeStuff()的定义:

function changeStuff(num, obj1, obj2)
{
    num = num * 10; // 对num赋值,修改num的指向,新内存的内容为old_num * 10
    obj1.item = "changed";  // 修改原始obj1内存中的内容
    obj2 = {item: "changed"};   // 对obj2赋值,修改obj2指向,新内存的内容为{item: "changed"}
}

这里我们忽略num = num * 10具体是如何完成的。这依赖于具体语言的解释器,实际上包含了数个对指针的操作。

由于call-by-sharing本质上也是传值,因此,也可以说JavaScript的传参方式都是传值。
当传递原始类型值给形参时,传递的就是原始值本身。
当传递引用类型值给形参时,传递的是一个指针(一个特殊的值)。

除了JavaScript之外,Python, Java, Ruby, Scheme等语言也是采用call-by-sharing的求值策略。

#!/usr/bin/python
#coding:utf-8
num = 10
obj1 = {"item": "unchange"}
obj2 = {"item": "unchange"}
print(id(num))
print(id(obj1))
print(id(obj2))
print("********")
def c(num, obj1, obj2):
    print(id(num))
    print(id(obj1))
    print(id(obj2))
    num = num * 10
    obj1["item"] = "changed"
    obj2 = {"item": "changed"}
    print("-------")
    print(id(num))
    print(id(obj1))
    print(id(obj2))
c(num, obj1, obj2)

print(num)
print(obj1)
print(obj2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值