JavaScript中函数参数的按值传递与按引用传递(即按地址传递)

首先声明一句:JavaScript中所有函数的参数都是按值传递的!不存在按引用传递!

在讲传递参数之前我们先来讲一下指针。

学过C指针的应该都知道,指针变量中保存的是一个地址,程序可以根据所保存的地址访问内存中对应的值并进行操作,如下图:

其中地址为0x00000016保存的是一个地址,指向地址0x00000036,即0x00000016被开辟为一个指针变量,可以引用0x00000036地址的值,这是按引用方式访问变量;另外一种访问变量的方式是按值访问,即图中0x00000008地址。

在JavaScript中有两种数据类型:基本类型和引用类型。其中,基本类型使用按值方式访问变量,引用类型使用按引用方式访问变量(而且JavaScript不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间。在操作对象时,实际上是在操作对象的引用而不是实际的对象)。

因为基本类型和引用类型采用的访问方式不同,所以造成了两个操作上的区别,分别是传递参数复制变量值

好了,回到主题。一般来说,传递参数有两种方式:按值传递和按引用传递。那么两种方式有什么不同呢?

  • 按值传递,即直接将变量的值传递到函数的参数中。打个比方,有一个String基本类型变量test的值为"Hello"(即var test = "Hello";),在传递参数时被传递的是值"Hello",因而无论在函数中对参数进行怎样的操作都不会影响到变量test。如下图:

  • 按引用传递,即将变量的地址传递到函数的参数中。因为JavaScript不存在按引用传递,所以我举一个C语言的例子,假设有一个函数void test(int *a){*a = *a + 10;},在main函数中这么调用“int b = 10;test(&b);”,此时,在test函数的参数传递过程中是将b的地址传递到test函数的参数a中,因而在函数中对参数进行操作可以反映到函数外。如下图:

 

看到这里,可能大家都发现,按值传递和按引用传递有一个很明显的区别:当使用按值传递时,在函数中对参数进行操作不会影响到函数外对应的变量;使用按引用传递时则会影响。

用过JavaScript的都知道,当传递引用类型的变量时,在函数中对参数进行操作会影响到函数外对应变量!于是有些小伙伴则认为:引用类型是按引用传递的。很抱歉的是,JavaScript中不存在按引用传递,所有参数都是按值传递

那么问题来了,为什么引用类型使用按值传递却会影响函数外对应的变量呢?

这是因为,引用类型的变量本就是一个引用,它的值是堆内存中Object的地址,当使用按值传递时传递的值本就是一个地址,所以在函数中对参数进行操作会影响到函数外对应的变量

posted @ 2015-03-15 03:38  钱杰明  阅读(2017)  评论(0编辑  收藏  举报