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

先来看一段代码

var source = [
{
name: 'dapianzi',
born: '2013',
more: {
width: 128,
}
},
{
sex: 'female',
more: {
weight: 48,
height: 168,
}
},
{
name: 'any'
}
];
var default = {
name: 'nobody',
born: '1990',
sex: 'man',
more: {
width: 666,
height: 888,
width: 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() 为啥要这样实现,是从性能的角度考虑,还是方便调用?(方便个鬼啊,很容易就踩坑了)

关于jquery.extend()的坑:我的数组变成相同元素了?的更多相关文章

  1. jQuery extend方法使用及实现

    一.jQuery extend方法介绍 jQuery的API手册中,extend方法挂载在jQuery和jQuery.fn两个不同对象上方法,但在jQuery内部代码实现的是相同的,只是功能却不太一样 ...

  2. jQuery.extend()方法和jQuery.fn.extend()方法源码分析

    这两个方法用的是相同的代码,一个用于给jQuery对象或者普通对象合并属性和方法一个是针对jQuery对象的实例,对于基本用法举几个例子: html代码如下: <!doctype html> ...

  3. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  4. 对jQuery.extend()方法的分析

    jQuery.extend方法是我们常用的方法,也是jQuery源码中的基础方法.它的主要作用是:将一个或多个“源对象”合并到一个“目标对象”中,并返回目标对象.它主要有三种表现形式: a.jQuer ...

  5. jQuery 源码分析4: jQuery.extend

    jQuery.extend是jQuery最重要的方法之一,下面看看jQuery是怎样实现扩展操作的 // 如果传入一个对象,这个对象的属性会被添加到jQuery对象中 // 如果传入两个或多个对象,所 ...

  6. jQuery.extend方法和开发中变量的复用

    最近在用commonJS规范进行客户端开发,遇到如下问题: 一般一个模块内部可能会定义一系列变量或一系列相关变量,比如写了一个颜色选择弹框模块大概会有如下变量定义 var settings = { / ...

  7. jQuery extend方法介绍

    jQuery为开发插件提拱了两个方法,分别是: jQuery.fn.extend(object); jQuery.extend(object); jQuery.extend(object);为扩展jQ ...

  8. jQuery.extend 和 jQuery.fn.extend

    1.jQuery.extend 我们先把jQuery看成了一个类,这样好理解一些.jQuery.extend(),是扩展的jQuery这个类. 假设我们把jQuery这个类看成是人类,能吃饭能喝水能跑 ...

  9. 大虾翻译(一):jQuery.extend()

    本文是在JavaScript之三里面链接内容的中文翻译.我会尽可能做到信达雅且保持作者原意不变,OK,let's Go! jQuery.extend(target,[object1],[objectN ...

随机推荐

  1. RuPengWang项目

    项目 Day1------------------------- 说明:建外键约束.ashx+Razor RupengWang创建三个类库Model DAL BLL后台:RupengWang.Admi ...

  2. TFSEclipsePlugin-UpdateSiteArchive 手动拷贝

  3. 伪差IO分标准

    伪差分电平 所谓伪差分电平,就是信号在接收端是一个差分的接收器,但其中一端固定接参考电压,而另一端接单端信号线.输入信号电压与参考电压之间进行比较,作为判断输入信号高低的标准. 常用的伪差分电平标准有 ...

  4. H264系列(9):H264中的时间戳(DTS和PTS)

    (1)Ffmpeg中的DTS 和 PTS H264里有两种时间戳:DTS(Decoding Time Stamp)和PTS(Presentation Time Stamp). 顾名思义,前者是解码的时 ...

  5. JDK 8 - JVM 对类的初始化探讨

    在<深入理解 Java 虚拟机>(第二版,周志明著)中,作者介绍了 JVM 必须初始化类(或接口)的五种情况,但是是针对 JDK 7 而言的. 那么,在 JDK 8 中,这几种情况有没有变 ...

  6. 【转】 Pro Android学习笔记(八四):了解Package(3):包间数据共享

    目录(?)[-] 共享User ID的设置 共享资源例子 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowing ...

  7. .Net Memory Profiler入门

    简介:http://www.cnblogs.com/wmlunge/archive/2013/01/08/2850809.html 实践: http://www.cnblogs.com/eaglet/ ...

  8. 关于struts2.3的action

    struts2.3中支持实时配置,也就是说不用在struts.xml中进行配置.但是所有的action文件应该放在有路径名含action的包中,否则程序无法发现你的action. 这个问题,难为了我好 ...

  9. queue队列模块

    import Queue myqueue = Queue.Queue(maxsize = 10) Queue.Queue类即是一个队列的同步实现.队列长度可为无限或者有限.可通过Queue的构造函数的 ...

  10. 第3章 ZooKeeper基本数据模型 3-1 zk数据模型介绍

    基本数据模型是zookeeper的重点. 它是参照Linux/Unix的目录结构. 子节点就相当于是父目录下的一个子目录,在zookeeper里面它是称之为节点,父节点和子节点,然后每一个节点就会有一 ...