值和引用

function foo(x) {
    x.push(4);
    console.log(x); //1,2,3,4
    x = [4, 5, 6];
    x.push(7);
    console.log(x);//4,5,6,7
}
var a = [1, 2, 3];
foo(a);
console.log(a);//1,2,3,4

在传递a的时候,其实是将引用a的一个复本赋值给x,而a仍然指向x,在方法中,我们可以通过x来改变数组的值,然后重新赋值x=[4,5,6],但这病不影响a的指向
所以我们不能通过引用x来更改引用a的指向,只能更改a和x共同指向的值
如果要改变原值,就必须改变x指向的数组,而不是为x赋值一个新的数组,例如:

function foo(x) {
    x.push(4);
    console.log(x); //1,2,3,4
    x.length = 0;
    x.push(4, 5, 6,7);
    console.log(x);//4,5,6,7
}

请记住,我们无法自行决定使用值复制还是引用复制,一切由值的类型来确定。
如果通过值复制的方式来传递复合数组,就需要为其创建一个复本,例如:

foo(a.slice());

相反如果要将基本类型的值传递到函数中并进行更改,就需要将值封装到一个复合对象中,然后进行传递。

function foo(o) {
    o.a = 11;
}
var obj = {
    a:2
}
foo(obj);
console.log(obj.a);

在看下基本类型对象传递时的问题:

 function foo(x) {
            x = x + 1;
            console.log(x);
        }

        var a = 2;
        var b = new Number(a);//object(a)也一样
        foo(b);
        console.log(b);//2

上面虽然传递的是对象的引用,但是也并未更改函数外部的值,原因是标量的基本类型值是不可以更改的(字符串和布尔也是如此),如果一个数字对象的标量基本类型值是2,那么该值就不能更改,
除非创建一个包含新值的数字对象。
x=x+1中,x中的标量基本类型值2从数组对象中拆封出来后,x就神不知鬼不觉的从引用变成了数字对象,他的值为3,然而函数外的b仍然指向原来的那个值为2的对象。

 

posted @ 2016-11-10 17:12  8932809  阅读(269)  评论(0编辑  收藏  举报