• 值和引用


    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的对象。

  • 相关阅读:
    z-index坑
    一些常用的可以封装好的方法
    echarts线状图
    vue 用js复制内容
    Java并发系列
    ThreadLocal讲解
    TreeMap源码学习
    HashMap源码学习
    Java Socket编程
    socket、tcp、udp、http 的认识及区别
  • 原文地址:https://www.cnblogs.com/y8932809/p/6051664.html
Copyright © 2020-2023  润新知