zoukankan      html  css  js  c++  java
  • 关于jquery.extend()的坑:我的数组变成相同元素了?

    首先呢我有一个数组,存放了多个json对象。这些json对象的属性有缺失,我设置了一个对象模板来存放默认值

    先来看一段代码

    var source = [
        {
            name: 'dapianzi',
            born: '2013',
            more: {
                 128,
            }
        },
        {
            sex: 'female',
            more: {
                weight: 48,
                height: 168,
            }
        },
        {
            name: 'any'
        }
    ];
    var default = {
        name: 'nobody',
        born: '1990',
        sex: 'man',
        more: {
             666,
            height: 888,
             777,
        }
    };
    // for (var i in source)
    // for (var i=0; i<source.length; i++)
    // source.forEach()
    source = source.map(function(item, key){return $.extend(true, default, item);});
    console.log(source);
    

    运行结果

    ???
    为什么数组元素全部变成一样的了???

    关于javascript 中的对象赋值

    var a = {x: 1, y: 2};
    var b = a;
    b.z = 3;
    console.log(b); // {x:1, y:2, z:3}
    console.log(a); // {x:1, y:2, z:3}
    

    可以看出对一个变量赋值其他的对象变量,是直接赋值引用的(道理我都懂,为什么数组元素变成一样的了??)

    jQuery.extend() 的实现

    之前使用 $.extend() 的场景比较单一,都是单一默认配置项的继承。
    这次的场景不一样的地方在于,在一个循环体里面,默认的配置项需要使用多次,并且使用了变量存储。

    关键的地方来了,查阅jQuery文档发现了这么一段话

    是说传入的第一个非布尔参数(布尔true表示深度拷贝继承)是会被改变的!
    也就是说,上面的代码实际上类似于这样:

    var source = [{x:1},{x:2},{x:3},];
    var opt = {y: 0};
    for (var i in source) {
        var tmp = opt;
        // opt extend source item.
        tmp.x = source[i].x; // 等价于 opt.x = source[i].x
        source[i] = tmp; // 等价于 source[i] = opt
    }
    

    执行之后 source 里面的元素是什么情况呢?

    [opt, opt, opt]
    

    因此我们会看到数组元素全部变成相同的了。

    反思总结

    • 对别人造的轮子不熟悉,想当然地认为是自己想象中的实现
      我想当然的认为它的实现方式
    function(a, b){
        var tmp = {}
        for (var i in a) {
            tmp[i] = a[i]
        }
        for (var j in b) {
            tmp[j] = b[j]
        }
        return tmp;
    }
    
    • 奇怪 jQuery.extend() 为啥要这样实现,是从性能的角度考虑,还是方便调用?(方便个鬼啊,很容易就踩坑了)
  • 相关阅读:
    mysql权限设置
    linux修改文件所属用户和组
    修改solaris 用户密码默认8位长度
    解决Solaris /home目录下无法创建目录问题
    MySQL修改root密码的多种方法
    solaris 安装jdk
    iPhone ZBar库 中文乱码解决方法重新编译libzbar.a
    ios中调用WCF
    Android自动在线升级(服务器为Tomcat)
    String字符串讲解
  • 原文地址:https://www.cnblogs.com/dapianzi/p/8926709.html
Copyright © 2011-2022 走看看