首先呢我有一个数组,存放了多个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. 【转】 Pro Android学习笔记(八三):了解Package(2):包签名过程

    目录(?)[-] 类比例子 数字签名 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ 在W ...

  2. Java学习之系统高可用性渲染接口日志自动服务降级

    背景:公司都追求系统的高可用性,这里不可用时间就是其中很重要的一个指标,为此在做系统功能升级迭代的过程中如何快速处理异常恢复正常功能极为重要.现在对新增模块的要求是都增加开关,方便快速关闭异常模块,但 ...

  3. wp8安装SSL证书

    把证书打成zip包,wp8的IE能下载并打开ZIP包,然后点击cer文件,就能安装证书了

  4. app自动更新(android)

    更新插件代码:https://github.com/shixy/UpdateApp 来源:http://aspoems.iteye.com/blog/1897300 检查更新的时候,通过指定的URL获 ...

  5. SpringBoot外部配置

    Spring Boot的配置文件 Spring Boot使用一个全局的配置文件application.properties或者application.yml(yaml语言的配置文件),放置在src/m ...

  6. C# Remoting 简单实现

    此处下载源代码(VS2010编译通过)   http://files.cnblogs.com/files/qqhfeng/%E8%BF%9C%E7%A8%8B%E8%B0%83%E7%94%A8%E6 ...

  7. hadoop-2.6.0.tar.gz + spark-1.6.1-bin-hadoop2.6.tgz + zeppelin-0.5.6-incubating-bin-all.tgz(master、slave1和slave2)(博主推荐)(图文详解)

    不多说,直接上干货! 我这里,采取的是CentOS6.5,当然大家也可以在ubuntu 16.04系统里,这些都是小事 CentOS 6.5的安装详解 hadoop-2.6.0.tar.gz + sp ...

  8. ssh框架整合其他方式(没有hibernate核心配置文件)

  9. ???Spring集成MyBatis02 【不推荐使用,了解即可】

    2017年5月19日09:31:22 由于该种方法比较麻烦,所以三少暂时不更新,哈哈哈:待更新...

  10. DB2--值为null则赋默认值

    数据库sql操作经常会做一些null值的处理.如果一个字段的值为null,我们希望查询出的结果默认设为0或空,则使用函数 COALESCE(column,0)  ,0的位置可以替换为其他值,可以是'' ...