理解js中函数参数的值传递

        在JavaScript中,访问变量有按值(访问基本类型)和按引用(访问引用类型)两种方式,但函数的参数值传递只能按值传递。
首先记住一句话:把函数外部的值传递给函数的形参,就和把值从一个变量复制到另一个变量一样。

一、引用类型的变量复制

        众所周知在js中声明了引用类型的变量时,变量名其实只是一个指向堆内存的引用,保存的是数据在堆内存中的地址,引用类型数据的存储形式如下图所示:
在这里插入图片描述
        当把值从一个变量复制到另一个变量时(注意这里说的是值的复制,而不是深拷贝),其实是让新的变量也指向内存中的同一个位置,如下图所示:
在这里插入图片描述

二、值传递

1.基本类型的值作为参数传递时很容易理解,不必赘述。
2.参数传递引用类型
        所谓值传递的意思是:把内存中的对象(也就是真正的值)传递给形参,那么如何实现呢?其实只需让形参也指向这个内存中的对象,实现方法就是把实参中的内存地址复制给形参。这个过程与上面的两张图所描述的过程是一样的,其中obj相当于实参,而obj2相当于形参。也正对应了开头的那句话:把函数外部的值传递给函数的形参,就和把值从一个变量复制到另一个变量一样。
        但从图中可以看出,如果给obj2.a重新赋值,那么通过obj.a访问的值也会变化,也就是说在函数内部修改了形参值,函数外部的实参也会变化,来看下面的代码:

function setName(obj) {
    obj.name = "Nicholas";
}
let person = new Object();
setName(person);
console.log(person.name); // Nicholas

        js的值传递确实有这样的“问题”——当传递的参数是引用类型时,函数内部的修改会被反映到函数外部。这样的结果确实容易让人误认为函数参数是引用传递的,再来看下面的代码:

function setName(obj) {
    obj.name = "Nicholas";
    obj = new Object(); // 修改了形参的地址引用
    obj.name = "Greg";
}
let person = new Object();
setName(person);
console.log(person.name); // 还是Nicholas

        函数内部的形参被重新赋值时,也就是形参指向了一个新的地址,此后对形参的修改不会再影响实参。如果参数是引用传递的,那么实参依然会随着形参的变化而变化,这就说明函数参数的传递不是引用传递。

三、总结

  • 值传递听起来像深拷贝,但不能理解为深拷贝,也就是说不能理解为:在内存中又创建了一个一模一样的对象,然后让形参指向这个对象;
  • 传递的是引用类型时,传递过来的只是实参的一个地址引用,即形参获得的也是一个地址引用,此时形参与实参指向的堆内存是相同的。所以值传递的值可理解为“内存地址”,传递可理解为“复制”。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值