JavaScript javascript 的传值问题

Daniel_Xu · 2014年04月15日 · 最后由 TsingHan 回复于 2014年04月15日 · 2589 次阅读

我一直以为 javascript 传参数是 简单的复制一份原本,可是最近 在我写一个小东西 (Tic-Tac-Toe 游戏) 的时候,一个 bug 调试了 1 整天,后来才发现了这个问题,大家看看,以后都注意下:

repo: https://github.com/Daniel-Xu/Tic-Tac-Toe

代码用了 require.js 和 underscore.js 稍微重构了一下,喜欢的给个 star

先上代码:

function test(num, obj1, obj2) 
{
    num  = 20
    obj1.name = "daniel-xu"
    obj2 = {name: "hello"}
}

var num = 10;
var obj1 = {name: "hello"}
var obj2 = {name: "hello"}

console.log("num is: ", num)
console.log("obj1 is: ", obj1)
console.log("obj2 is: ", obj2)

test(num, obj1, obj2)

console.log("num is: ", num)
console.log("obj1 is: ", obj1)
console.log("obj2 is: ", obj2

答案是:

num is:  10
obj1 is:  { name: 'hello' }
obj2 is:  { name: 'hello' }
num is:  10
obj1 is:  { name: 'daniel-xu' }
obj2 is:  { name: 'hello' }

现象解释

It's always pass by value, but for objects the value of the variable is a reference

总是按值传递,但是对于 object,这个参数本身是一个引用。我来解释下这句话。

比如 num 这个,函数里面的 num 只是一个副本,所以 外面的值没变化

同理 obj2 这个值,虽然 obj2 这个值是一个 reference(即引用),但是test 函数体中只是参数 obj2 的一个副本,所以,它也没有变。函数一退出,作用域就结束了

而对 obj1,虽然函数体中的也是 一个副本,但是引用指向的还是同一个对象,所以改变 对象的属性,就会永久改变。

resource

http://snook.ca/archives/javascript/javascript_pass

题外话

感觉 chrome 的 debug 越来越好用了。

@Daniel_Xu 相当好的例子,在平时的应用中很可能因为这个造成困惑,thanks

需要 登录 后方可回复, 如果你还没有账号请 注册新账号