jQuery源码之extend的实现

时间: 2019-08-07阅读: 153标签: 源码

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 }}

简单的从结果来看,返回的结果并不符合我们的预期,基础版本的方法似乎只是简单的值替换而已。那么来简单升级一下代码吧。
在升级代码之前,需要了解一下关于浅拷贝和深拷贝的相关。


关于浅拷贝和深拷贝的那些事

浅拷贝

对于浅拷贝,我的简单理解就是: 浅拷贝就是对最表面的层级进行拷贝,如果某一被拷贝对象的值发生了改变,最终的拷贝结果也会随之发生改变。

      var i = {a: 0};
      var b = {c: 9};
      console.log($().extend(i,b)) // {a: 90, c:9}
      i.a = 90

深拷贝

深拷贝主要的是面对复杂对象,如果浅拷贝是对最表面的一层进行拷贝,那么深拷贝就是,对拷贝对象的每一个层级都进行拷贝,某种层面来说,勉强算得上是递归的浅拷贝吧,但是比较不同的是,深拷贝中,如果某一个被拷贝对象的值发生了改变,拷贝结果是不会随之发生变化的,是一个独立的存储空间。

   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。
基本思路:首先先对第一个传入参数进行判断,判断是否是boolean类型,来决定是否需要进行深拷贝;

   var deep = false;
   if (typeof target === 'boolean') {
     deep = target;
     target = arguments[1];
     i = 2;  //因为第一参数为boolean,所以拷贝对象从argument[1]开始,但通常第一个拷贝对象是不需要比遍历的,所以遍历下标从2开始。
   }

对需要遍历的对象进行判断,判断是否是复杂类型。使用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]';
     }
   })

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函数了,其实比较重要的是深拷贝和浅拷贝,关于这一点,下次再记录吧。


吐血推荐

1.阿里云: 本站目前使用的是阿里云主机,安全/可靠/稳定。点击领取2000元代金券、了解最新阿里云产品的各种优惠活动点击进入...

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各类产品的最新活动,优惠券领取点击进入...

3.站长广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入...

链接: http://www.fly63.com/article/detial/5185

精读Hooks 取数-swr源码

取数是前端业务的重要部分,也经历过几次演化:fetch 的兼容性已经足够好,足以替换包括 $.post 在内的各种取数封装。原生用得久了,发现拓展性更好、支持 ssr 的同构取数方案也挺好

哪些方面可以看出企业建站源码质量?

源代码是构成网站的核心,即网站程序代码,包括网站文件及目录结构,拥有源代码才拥有网站的全部。传统自助建站因其SAAS模式无法开放源代码,用户实质上是每年支付租金租用放在平台网站的使用权

Vue 3 源码开放了

于2019年10月5日凌晨,尤雨溪在微博宣布 Vue 3.0 的源码开放了。目前依然是 pre-alpha 状态,但主要的架构改进、优化和新功能都已经完成,剩下的主要是完成一些 Vue 2 现有功能的移植

JS源码解析之Array.prototype.sort

给一个 sort 的比较函数中返回0,表示当前比较的两个元素相等,照理说, sort(()=>0) 后数组的元素顺序是不变的,和我的测试效果一致,那为什么在 低版本的 chrome 上,不同长度的数组运用 sort(()=>0) 后效果不一样呢?

vue-next/runtime-core 源码阅读指南

最近又抽时间把 vue-next/runtime-core 的源码陆陆续续地看完了,期间整理了很多笔记,但都是碎片化的。本来是想整理一下,写成一篇文章分享出来的,但是感觉最终的成果物只能是一篇篇幅巨长的解析文,就算我一行一行的把源码加上注释

webpack 源码从零开始:apable模型

最近在看webpack的源码,发现有个比较头疼的点是:代码看起来非常跳跃,往往看不到几行就插入一段新内容,为了理解又不得不先学习相关的前置知识。层层嵌套之后,发现最基础的还是tapable模型,因此先对这部分的内容做一个介绍。

vue源码中的检测方法

判断是否为undefined或null; 判断是否为Promise 函数;判断是否为简单数据类型;严格检查复杂数据类型;将驼峰字符串转成连接符 magicEightTall 转换成 magic-eight-tall

vuex源码:state及strict属性

state也就是vuex里的值,也即是整个vuex的状态,而strict和state的设置有关,如果设置strict为true,那么不能直接修改state里的值,只能通过mutation来设置

扒开V8引擎的源码,我找到了你们想要的前端算法

算法对于前端工程师来说总有一层神秘色彩,这篇文章通过解读V8源码,带你探索 Array.prototype.sort 函数下的算法实现。来,先把你用过的和听说过的排序算法都列出来:

React源码解析之ExpirationTime

在React中,为防止某个update因为优先级的原因一直被打断而未能执行。React会设置一个ExpirationTime,当时间到了ExpirationTime的时候,如果某个update还未执行的话,React将会强制执行该update,这就是ExpirationTime的作用。

fly63.com版权所有,内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权,请与小编联系!情况属实本人将予以删除!

广告赞助文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全