extend是jQuery中一个比较核心的代码,如果有查看jQuery的源码的话,就会发现jQuery在多处调用了extend方法。

作用

  1. 对任意对象进行扩展
  2. 扩展某个实例对象
  3. 对jquery本身的实例方法进行扩展

实现

基础版本, 对简单对象进行扩展
   jQuery.prototype.extend = jQuery.extend = function(){
var target = arguments[0] || {}; //获取第一个参数作为目标结果
var i = 1; //设置开始扩展的下标,扩展时第一个参数不会进行改变,不需要遍历
var length = arguments.length;
var option;
if(typeof target !== 'object') {
target = {};
} for(; i< length; i++){
option = arguments[i]
for(var name in option){
target[name] = option[name]
}
}
return target
} //调用
var i = {a: 0};
var b = {c: 9};
console.log($().extend(i,b)) // {a:0, c:9}
升级版本1.0, 对复杂对象进行扩展。

在上面,我们已经写出的extend的基础版本,但是如果我们简单测试一下,就会发现仍是有问题存在的。

我们可以使用上面的方法,对下面的对象进行扩展

      var n = {
al: 90,
m: {
d: 23,
}
}
var b = {m:{
c: 98
}};
console.log($().extend(n,b)) // {al: 90, m: { c: 98 }}

简单的从结果来看,返回的结果并不符合我们的预期,基础版本的方法似乎只是简单的值替换而已。那么来简单升级一下代码吧。

在升级代码之前,需要了解一下关于浅拷贝和深拷贝的相关。

关于浅拷贝和深拷贝的那些事
  1. 浅拷贝,

    对于浅拷贝,我的简单理解就是: 浅拷贝就是对最表面的层级进行拷贝,如果某一被拷贝对象的值发生了改变,最终的拷贝结果也会随之发生改变。
      var i = {a: 0};
var b = {c: 9};
console.log($().extend(i,b)) // {a: 90, c:9}
i.a = 90
  1. 深拷贝,深拷贝主要的是面对复杂对象,如果浅拷贝是对最表面的一层进行拷贝,那么深拷贝就是,对拷贝对象的每一个层级都进行拷贝,某种层面来说,勉强算得上是递归的浅拷贝吧,但是比较不同的是,深拷贝中,如果某一个被拷贝对象的值发生了改变,拷贝结果是不会随之发生变化的,是一个独立的存储空间。
   var n = {
al: 90,
m: {
d: 23,
}
}
var b = {m:{
c: 98
}};
console.log($().extend(true,{},n,b))
console.log(n)
n.al = "cs"

结果:

深拷贝extend代码扩展

jQuery.extend是提供深拷贝的,需要将第一参数传为true。

基本思路:

  1. 首先先对第一个传入参数进行判断,判断是否是boolean类型,来决定是否需要进行深拷贝;
   var deep = false;
if (typeof target === 'boolean') {
deep = target;
target = arguments[1];
i = 2; //因为第一参数为boolean,所以拷贝对象从argument[1]开始,但通常第一个拷贝对象是不需要比遍历的,所以遍历下标从2开始。
}
  1. 对需要遍历的对象进行判断,判断是否是复杂类型。使用extend对jquery进行扩展。
   if (length === i) { //此时extend参数只有一个,但是目标应该是this,所以获取到this;
target = this; //但同时 i = 1;无法进行遍历,所以将遍历下标后退一位
i--;
} jQuery.extend({
isArray: function(obj) {
return toString.call(obj) === '[object Array]';
},
isPainObj: function(obj) {
return toString.call(obj) === '[object Object]';
}
})
  1. extend方法改造。
   jQuery.prototype.extend = jQuery.extend = function(){
var target = arguments[0] || {};
var i = 1;
var length = arguments.length;
var option, copy, src, copyisArray, clone;
for(; i< length; i++){
if((option = arguments[i]) != null ){
for(name in option) {
src = target[name];
copy = option[name];
if(jQuery.isPainObj(copy) || (copyisArray = jQuery.isArray(copy))) {
if(copyisArray) {
copyisArray = false;
clone = src && jQuery.isArray(src) ? src : [];
} else {
clone = src && jQuery.isPainObj(src) ? src : {};
}
target[name] = jQuery.extend(clone,copy)
} else if(copy !== undefined) {
target[name] = copy
}
}
}
}
return target
}

行了,到这里为止,我们就已经完成了简单的extend函数了,其实比较重要的是深拷贝和浅拷贝,关于这一点,下次再记录吧。

jQuery源码二之extend的实现的更多相关文章

  1. jquery源码学习之extend

    jquery的extend方法现项目中经常使用,现在了解一下它的实现. 说起extend就要先了解一个jQuery的$.extend和$.fn.extend作用及区别 jQuery为开发插件提拱了两个 ...

  2. JQuery源码之“名叫extend的继承”

    提起JS中的继承很多”大神“们都会提起call,apply,单纯的对象赋值继承,以及原型链继承等众多的方式以及它们的不足之处,而且还会不时的把一些面向对象的设计模式”团团“的带出来,可谓是厉害非常啊! ...

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

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

  4. jquery源码学习笔记二:jQuery工厂

    笔记一里记录,jQuery的总体结构如下: (function( global, factory ) { //调用factory(工厂)生成jQuery实例 factory( global ); }( ...

  5. jquery源码分析(二)——架构设计

    要学习一个库首先的理清它整体架构: 1.jQuery源码大致架构如下:(基于 jQuery 1.11 版本,共计8829行源码)(21,94)                定义了一些变量和函数jQu ...

  6. Jquery源码中的Javascript基础知识(二)

    接上一篇,jquery源码的这种写法叫做匿名函数自执行 (function( window, undefined ) { // code })( window ); 函数定义了两个参数window和u ...

  7. 车大棒浅谈jQuery源码(二)

    前言 本来只是一个自己学习jQuery笔记的简单分享,没想到获得这么多人赏识.我自己也是傻呵呵的一脸迷茫,感觉到受宠若惊. 不过还是有人向批判我的文章说,这是基本知识点,完全跟jQuery源码沾不上边 ...

  8. 读jQuery源码 - Deferred

    Deferred首次出现在jQuery 1.5中,在jQuery 1.8之后被改写,它的出现抹平了javascript中的大量回调产生的金字塔,提供了异步编程的能力,它主要服役于jQuery.ajax ...

  9. jQuery源码笔记(一):jQuery的整体结构

    jQuery 是一个非常优秀的 JS 库,与 Prototype,YUI,Mootools 等众多的 Js 类库相比,它剑走偏锋,从 web 开发的实用角度出发,抛除了其它 Lib 中一些中看但不实用 ...

随机推荐

  1. String数组转int数组

    假设我们有一个字符串数组: String[] strings = {"1", "2", "3"}; 使用Lambda表达式(自Java 8起 ...

  2. NOIP2013-2014提高组题目浅析

    1.前言 迎接NOIP的到来...在这段闲暇时间,决定刷刷水题.这里只是作非常简单的一些总结. 2.NOIP2014 <1> 生活大爆炸之石头剪刀布(模拟) 这是一道考你会不会编程的题目. ...

  3. 【可持久化0/1Trie】【P4735】最大异或和

    Description 给定一个长度为 \(n\) 的序列 \(A\),有 \(m\) 次操作,每次要么在序列尾部再添加一个数,将序列长度 \(n\) 加一,要么给进行一次查询,给定查询参数 \(l, ...

  4. sharding-jdbc 分布式数据库中间件

    小编今天在做Sharding-jdbc时出现了一些问题,就上网百一百,发现网上的sharding-jdbc的参考是挺少的,唉还是要继续学习看文档. Sharding-jdbc介绍 Sharding-J ...

  5. centos7 安装 mysql5.7.25

    一.检查是否安装了mysql和mariadb,若已经安装就需要卸载. [root@localhost ~]# rpm -qa|grep mariadb // 查询出来已安装的mariadb [root ...

  6. apply() 函数家族介绍

    apply() 函数算是R语言中很基础的一个函数,同时还有 sapply()  lapply()  tapply() 函数精简了 apply() 函数的用法. apply() 函数是一个很R语言的函数 ...

  7. 2018-2019-2 20165315《网络对抗技术》Exp 8 Web基础

    2018-2019-2 20165315<网络对抗技术>Exp 8 Web基础 一.实验内容 Web前端HTML 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST ...

  8. Beta/Gamma事后分析

    目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结 对照敏捷开发的原则, 你觉得你们小组做得最好的是哪几个原则? 请列出具体的事例. 照片 设想和目标 我们的 ...

  9. Gamma阶段第七次scrum meeting

    每日任务内容 队员 昨日完成任务 明日要完成的任务 张圆宁 #91 用户体验与优化https://github.com/rRetr0Git/rateMyCourse/issues/91(持续完成) # ...

  10. 【Gamma阶段】第八次Scrum Meeting

    冰多多团队-Gamma阶段第八次Scrum会议 工作情况 团队成员 已完成任务 待完成任务 卓培锦 编辑器风格切换(添加夜间模式) UI界面手势切换 牛雅哲 添加pytorch训练dict和ssh工具 ...