# 定义

在 《JavaScript 高级程序设计》讲到传递参数:

ECMAScript 中所有函数的参数都是按值传递的。

什么是按值传递?

也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制给另一个变量一样。

# 按值传递

举个例子

var value = 1
function foo(v) {
  v = 2
  console.log(v) // 2
}

foo(value)
console.log(value) 1

很好理解,当传递 value 到函数 foo 中,相当于拷贝了一份,所以在函数中修改的都是拷贝的值,而不是原值。

# 引用传递?

拷贝虽然很好理解,但是如果一个值的数据结构很复杂的时候,如果拷贝的话性能就会比较差。

所以还有另一种方式叫 引用传递

所谓引用传递就是传递对象的引用,函数内部对参数的任何改变都会影响该对象的值。

举个例子:

var value = {
  a: 1,
}

function foo(v) {
  v.a = 2
  console.log(v.a) // 2
}

foo(value)
console.log(value.a) // 2

但是,很奇怪,红宝书说了 ES 都是按值传递啊,怎么能按引用传递成功呢?

这究竟是不是按引用传递?

# 共享传递

让我们再看一个例子:

var value = {
  a: 1,
}

function foo(v) {
  v = 2
  console.log(v) // 2
}

foo(value)
console.log(value) // { a: 1 }

如果 ES 采用的是引用传递的话,内部修改了值,外部的值也会跟着修改,但是事实是并没有修改,所以 ES 并不是采用按引用传递。

所以,事实上,ES 采用的共享传递。

共享传递:在传递对象的时候,传递对象的引用副本。

注意:按引用传递是传递对象的引用,而按共享传递则是传递对象应用的副本!

# 结论

参数是基本类型则按值传递,参数是引用类型则按共享传递