JS语言理解16 函数参数的传值调用方式

学习了JavaScript 是传值调用还是传引用调用?@nodejh/nodejh.github.io的文章,了解了函数参数的传值调用方式,基本类型是传值调用,引用类型是传共享调用

函数参数的传递方式

一般来说有三种参数传递方式:

(1)传值调用

传值调用时,来传递给函数参数时函数被调用时所传实参的拷贝,其值会被绑定到函数对应的变量上(通常是把值复制到新内存区域)。

(2)传引用调用

传引用调用是,传递给函数的是它的实际参数的隐式引用而不是实参的拷贝。函数能够修改这些参数,而且改变时对调用者可见的。

(3)传共享调用

传共享调用和传引用调用的不同之处是,这种方式传递给函数参数的是对象引用的拷贝,即对象变量指针的拷贝

JavaScript中采用的是哪种传值调用方式呢?先给出结论:

基本类型是传值调用,引用类型是传共享调用

这与《JavaScript高级程序设计》中的结论是JavaScript参数传递是不矛盾的,因为传值调用本质上传递的是变量的值的拷贝,而传共享调用本质上是传递对象的指针的拷贝,指针也是变量的值,所以传共享调用也可以说是传值调用

具体如何理解呢,先看一个例子

如何理解

看这样的一道题目:

function changeStuff(a, b, c) {
  a = a * 10;
  b.item = "changed";
  c = {item: "changed"};
}

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

changeStuff(num, obj1, obj2);

console.log(num);
console.log(obj1.item);    
console.log(obj2.item);

输出的结果是:

10
changed
unchanged

为什么会这样呢?一步一步来分析

代码分析

(1)变量初始化

var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};

这个时候内存分配情况如下:

(2)调用函数

changeStuff(num, obj1, obj2);

函数的参数就是函数作用域内的变量,

变量a是基本类型,它的传递是传值调用,所以a的值就是num的拷贝,而obj1obj1是引用累心个,所以bc分别是obj1obj2指针的拷贝

(3)函数执行

a = a * 10;
b.item = "changed";
c = {item: "changed"};

anum的拷贝,所以a的改变不会影响到num,所以num仍为10

bobj1指向同一个对象,对其属性的更改实际上是对指针指向的内存中的变量的更改,所以b.item的更改会造成obj1.item随之更改

cobj2原本由于指针的拷贝,指向的也是同一个对象,但是由于在函数中对c重新赋值,指向了另一块内存中的新的变量,所以对c的更改不会影响到obj2

结论

JavaScript中函数参数调用时:基本类型是传值调用,引用类型是传共享调用

参考

发布了382 篇原创文章 · 获赞 91 · 访问量 33万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览