jQuery源碼二之extend的實現

来源:https://www.cnblogs.com/xya-b/archive/2019/09/06/11472611.html
-Advertisement-
Play Games

extend是jQuery中一個比較核心的代碼,如果有查看jQuery的源碼的話,就會發現jQuery在多處調用了extend方法。 作用 1. 對任意對象進行擴展 2. 擴展某個實例對象 3. 對jquery本身的實例方法進行擴展 實現 基礎版本, 對簡單對象進行擴展 jQuery.prototy ...


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"

結果:
Image text

深拷貝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函數了,其實比較重要的是深拷貝和淺拷貝,關於這一點,下次再記錄吧。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本來是想做一個滑鼠點擊事件:A,B兩個東西,B先隱藏,點擊A,B出現,再點一次A,B消失,然後發現在判斷不同的情況下,出現了一點小問題 暫時沒有問題的寫法: 然後,我把它的判斷條件改了一下,其實這是我第一次寫的想法: 然後它的效果是,第一次點擊的時候沒有反應,要點第二次,B才會出來,有點不明白 ...
  • (馬蜂窩技術原創內容,公眾號 ID:mfwtech) 一份來自 Akamai 的研究報告顯示,在對 1048 名網購戶進行採訪後發現: 約 47% 的用戶期望他們的頁面在兩秒之內載入完成。 如果頁面載入時間超過 3s,約 40% 的用戶會選擇離開或關閉頁面。 約 47% 的用戶期望他們的頁面在兩秒之 ...
  • Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式,它採用集中式存儲管理應用的所有組件的狀態,註意:使用前需要先載入vue文件才可以使用(在node.js下需要使用Vue.use(Vuex)來安裝vuex插件,在瀏覽器環境下直接載入即可,vuex會自行安裝) vuex的使用方法很簡單,首 ...
  • 在項目中常常需要用級聯地址,為了實現這個功能,大家肯定會瘋狂得找插件快速實現,但是博主就喜歡使用純js來實現。 首先建立一個二維數組,第一列存省,第二列存城市並用分隔符分隔 建立兩個一維數組,一個存省,一個存城市 創建兩個初始變數,一個存當前選中得省,一個存當前選中得城市 給省的select選擇框添 ...
  • 先貼一張圖片做個例子 看不清圖片的朋友可以右鍵圖片,在<新標簽頁中打開圖片>; 可以看到,由於內容過長,導致後面操作的增刪改要拉到最後才能操作. 在我們的FastAdmin中,目前我還沒找到可以調整列表大小的文檔,如果有,歡迎大家告知.下麵是我用來解決這個問題的方法 我們可以在生成的頁面好添加兩段代 ...
  • 1 2 3 4 5 Document 6 13 21 22 23 24 25 ...
  • 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style type="text/css"> 7 #div1{ 8 width: 200px; 9 ... ...
  • 上一篇我們主要講解了函數的執行過程和原理,本篇我們將介紹函數的另外兩個特殊表現:閉包和立即執行函數。 一 閉包 1, 閉包的形成 之前我們提到,函數執行完畢,馬上就會銷毀自己的AO對象。但是如果遇到下麵這種情況:有子函數的定義,並將子函數返回。它真的就完全銷毀了自己的AO對象嗎? 這將列印什麼呢?表 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...