zoukankan      html  css  js  c++  java
  • JavaScript语法细节——引用与复制

    我们都知道,JS中变量的赋值有两种方式,最近在折腾自己写的标签栏插件,碰到了很多平时没注意的问题。正好,那边处理清楚了,稍微整理一下关于引用与复制相关知识,可能会不定期增加新碰到的问题,有错误希望看到的人指出,避免传播不正确的知识。

    先大致分一下类,引用类型:Object以及其旗下的Array,Date,RegExp,Function;基本包装类型:Boolean,number,String。

    在赋值与传递参数的时候,引用类型传递的是指针,基本包装类型是复制新值传递。常见的情况我就不啰嗦了,一下主要是一些碰到过的容易理解出错的情况,以及探究后得出的个人结论。

    修改指针变量不一定会影响到引用对象

    可能一下不太好理解这个,来点简单暴力的demo就好说明问题了。

    var
        arr1 = [1, 2, 3],
        arr2 = arr1;
    arr2
    = [4, 5, 6];
    console.log(arr1); console.log(arr2);

    这个demo比较简单,结果是:arr1为[1, 2, 3]  arr2为[4, 5, 6]

    为什么修改arr2后arr1没有改变,arr2 = [4, 5, 6]修改的是arr2这个指针变量的指向,并没有碰到原引用的数组。

    下面这种情况则会修改到原对象。

    var
        arr1 = [1, 2, 3],
        arr2 = arr1;
    arr2.pop();
    console.log(arr1); console.log(arr2);

    此时的结果为: arr1 arr2都等于[1, 2],arr2.pop()相当于执行[1, 2, 3].pop(),因此arr2引用的原匿名对象被修改了。

    因此在操作引用类型的时候,要注意是否修改的是原对象。来一个稍微啰嗦有点的demo:

    var
        arr1 = [1, 2, 3],
        arr2 = arr1;
    
    function test (a) {
        console.log(a);
        a = [4, 5, 6];
        console.log(a);
    }
    
    test(arr2);
    
    console.log(arr1);
    console.log(arr2);

    上面的输出结果根据之前的测试应该是

    var
        arr1 = [1, 2, 3],
        arr2 = arr1;
    
    function test (a) {
        console.log(a); // [1, 2, 3]
        a = [4, 5, 6];
        console.log(a); // [4, 5, 6]
    }
    
    test(arr2);
    
    console.log(arr1); // [1, 2, 3]
    console.log(arr2); // [1, 2 ,3]

    因为在传递arr2给test的时候,相当于执行了a = arr2因此情况跟第一个demo一样了。同理,将a=[4, 5, 6]改为a.pop(),那么结果如同第二个demo。

    来一个函数自己修改自己的demo:

    var test = function () {
        var a = 1;
        test = function () {
            var b = 3;
        }
    };
    
    test();
    
    console.log(test);

    此时的test内部为var b = 3;这种方法有个高大上叫法叫惰性载入,具体我就不啰嗦了,可以百度一下或者谷歌两下。利用的就是函数本身也是引用类型的特点。

    下面的这个demo是引用类型中引用类型:

    var obj1 = {
            arr: [1, 2, 3]
        },
        obj2 = obj1;
    
    obj2.arr = [4, 5, 6];
    
    console.log(obj1);

    输出结果中,obj1被修改了,不难理解执行obj2.arr = [4, 5, 6]时,相当于执行obj1.arr = [4, 5, 6],直接修改了原对象。因此采用简单的赋值操作得不到一个对象的拷贝。取得拷贝的话可以用for(key in object)的方式遍历对象进行拷贝。

    至于原始类型字符串数字之类的基本类型就不多写了,那些都是复制操作,获得的是一个新值。

    欢迎纰漏。

  • 相关阅读:
    彻底理解cookie,session,token
    IP 别名和辅助 IP 地址
    1 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之DRBD的搭建
    centos配置DNS和ip
    centos的安装和下载
    activemq的学习
    mongodb的分片
    MongoDB的安装
    分布式事务中的三种解决方案详解(转载)
    redis中redis.conf配置文件解析
  • 原文地址:https://www.cnblogs.com/anginwei/p/4206729.html
Copyright © 2011-2022 走看看