首先呢我有一个数组,存放了多个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. 蓝桥杯 历届试题 PREV-32 分糖果

    历届试题 分糖果   时间限制:1.0s   内存限制:256.0MB 问题描述 有n个小朋友围坐成一圈.老师给每个小朋友随机发偶数个糖果,然后进行下面的游戏: 每个小朋友都把自己的糖果分一半给左手边 ...

  2. PostgreSQL 监控磁盘使用

    监控磁盘使用 1. 判断磁盘用量 每个表都有一个主要的堆磁盘文件,大多数数据都存储在其中.如果一个表有着可能会很宽(尺寸大)的列, 则另外还有一个TOAST文件与这个表相关联, 它用于存储因为太宽而不 ...

  3. git学习5 ecipse集成git(转载)

    原文地址:http://blog.csdn.net/hhhccckkk/article/details/10458159 有的eclipse已经自带了GIt了,就不用安装了 1: 进行安装Git,和安 ...

  4. windows下socket编程:区分shutdown()及closesocket()

    以下描述主要是针对windows平台下的TCP socket而言. 首先需要区分一下关闭socket和关闭TCP连接的区别,关闭TCP连接是指TCP协议层的东西,就是两个TCP端之间交换了一些协议包( ...

  5. 使用like查询text类型字段

    使用like查询text类型字段 public bool Exists(GetReadType GRT, ClientMessageGetRead TypeID, string MessageID, ...

  6. Log4j 记录error 日志

    第一个bug的起始,是在线上日志发现一个频繁打印的异常——java.lang.ArrayIndexOutOfBoundsException.但是却没有堆栈,只有一行一行的ArrayIndexOutOf ...

  7. eclipse中server location为灰色,不能修改

    Eclipse中tomcat service设置发布时间︰选择window ----show view---services可以看到服务的面板双击tomcat进入配置界面Service Locatio ...

  8. Spring MVC F5刷新问题

    转自:https://bbs.csdn.net/topics/390771056 post操作成功后重定向到B,这样浏览器里F5的时候就不会让提交A了    

  9. Consumer设计-high/low Level Consumer

    1 Producer和Consumer的数据推送拉取方式   Producer Producer通过主动Push的方式将消息发布到Broker n Consumer Consumer通过Pull从Br ...

  10. c# json.net xml互转

    json转xml: XmlDocument doc = (XmlDocument)JsonConvert.DeserializeXmlNode(jsonText,"root"); ...