整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          深入理解 JavaScript:實現(xiàn)自定義 `map

          深入理解 JavaScript:實現(xiàn)自定義 `map` 方法

          家好,很高興又見面了,我是姜茶的編程筆記,我們一起學習前端相關領域技術(shù),共同進步,也歡迎大家關注、點贊、收藏、轉(zhuǎn)發(fā),您的支持是我不斷創(chuàng)作的動力

          在 JavaScript 中,Array.prototype.map 是一個常用的方法,它對數(shù)組的每個元素調(diào)用提供的函數(shù),并返回一個新數(shù)組,包含函數(shù)的返回值。為了更好地理解其內(nèi)部機制,今天我們將從零開始,實現(xiàn)一個自定義的 map 方法,并詳細解析其實現(xiàn)步驟。

          實現(xiàn)自定義 map 方法

          首先,我們創(chuàng)建一個 myMap 方法,將其添加到 Array.prototype 上。這個方法接受兩個參數(shù):一個回調(diào)函數(shù) callback 和一個可選的 thisArg 參數(shù)。callback 函數(shù)將對數(shù)組的每個元素進行操作,thisArg 是執(zhí)行回調(diào)函數(shù)時的 this 值。

          Array.prototype.myMap=function(callback, thisArg) {
            // 將傳入的數(shù)組轉(zhuǎn)換為對象
            const O=Object(this);
          
            // 獲取數(shù)組的長度
            const len=O.length >>> 0;
          
            // 如果 callback 不是函數(shù),則拋出 TypeError
            if (typeof callback !=='function') {
              throw new TypeError(callback + ' is not a function');
            }
          
            // 創(chuàng)建一個新的數(shù)組,用于存儲映射結(jié)果
            const result=new Array(len);
          
            // 遍歷數(shù)組并應用回調(diào)函數(shù)
            for (let i=0; i < len; i++) {
              // 只有當元素在數(shù)組中存在時才進行映射
              if (i in O) {
                // 調(diào)用回調(diào)函數(shù),傳遞 thisArg 作為 this 值,并傳遞當前元素、索引、數(shù)組本身
                result[i]=callback.call(thisArg, O[i], i, O);
              }
            }
          
            return result;
          };
          

          讓我們逐步解析這個實現(xiàn)。

          1. 將傳入的數(shù)組轉(zhuǎn)換為對象

          我們首先將 this 轉(zhuǎn)換為一個對象,以便在方法中使用:

          const O=Object(this);
          

          2. 獲取數(shù)組的長度

          使用 >>> 0 操作符將長度轉(zhuǎn)換為無符號整數(shù),確保其為正整數(shù):

          const len=O.length >>> 0;
          

          3. 檢查回調(diào)函數(shù)

          如果 callback 不是函數(shù),則拋出一個 TypeError

          if (typeof callback !=='function') {
            throw new TypeError(callback + ' is not a function');
          }
          

          4. 創(chuàng)建結(jié)果數(shù)組

          我們創(chuàng)建一個與原數(shù)組長度相同的新數(shù)組,用于存儲映射結(jié)果:

          const result=new Array(len);
          

          5. 遍歷數(shù)組并應用回調(diào)函數(shù)

          使用 for 循環(huán)遍歷數(shù)組的每個索引。如果當前索引存在于數(shù)組中,則調(diào)用回調(diào)函數(shù),并將結(jié)果存儲在 result 數(shù)組中:

          for (let i=0; i < len; i++) {
            if (i in O) {
              result[i]=callback.call(thisArg, O[i], i, O);
            }
          }
          

          6. 返回結(jié)果數(shù)組

          最后,我們返回存儲映射結(jié)果的 result 數(shù)組:

          return result;
          

          示例使用

          下面是一個示例,展示如何使用自定義的 myMap 方法:

          const numbers=[1, 2, 3, 4, 5];
          const doubled=numbers.myMap(x=> x * 2);
          
          console.log(doubled); // 輸出 [2, 4, 6, 8, 10]
          

          在這個示例中,我們將 numbers 數(shù)組中的每個元素都乘以 2,并將結(jié)果存儲在 doubled 數(shù)組中。結(jié)果輸出為 [2, 4, 6, 8, 10],這與內(nèi)置的 Array.prototype.map 方法的行為一致。

          結(jié)論

          通過實現(xiàn)自定義的 map 方法,我們深入理解了 JavaScript 中數(shù)組的操作方式。希望你可以更好地掌握 map 方法的內(nèi)部機制,并提升你的 JavaScript 編程技巧。

          最后

          如果你有任何問題或建議,歡迎在評論區(qū)留言交流!祝你編程愉快!

          Map 對象

          Map 對象表示 HTML <map> 元素。

          訪問 Map 對象

          你可以使用 getElementById() 訪問 <map> 元素:

          var x=document.getElementById("myMap");

          創(chuàng)建 Map 對象

          你可以通過使用 document.createElement() 方法創(chuàng)建 <map> 元素:

          var x=document.createElement("MAP");

          Map 對象集合

          集合描述
          areas返回圖象地圖中所有 <area> 元素的集合
          images返回所有與圖象地圖相關 <img> 和 <object> 元素的集合

          Map 對象熟悉

          屬性描述
          name設置或返回圖像地圖的 name 屬性值

          標準屬性和事件

          Map 對象同樣支持標準的 屬性 和 事件。

          如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!

          ap、filter、reduce都是高階函數(shù),它們的功能非常強大,可以搭配箭頭函數(shù)來完成復雜的數(shù)組數(shù)據(jù)處理。關于它們的用法很多人寫過,但少有人寫結(jié)合案例來寫。在這里我會對這3個函數(shù)的用法結(jié)合案例來詳細講述,并額外寫了for循環(huán)版本用來幫助理解。

          模擬數(shù)據(jù)

          要詳細講述這3個高階函數(shù)的用法必須結(jié)合實際案例來講。現(xiàn)在有一個這樣的數(shù)組,這個數(shù)組是任務清單:

          let todo=[
              {id: 1, name: "吃飯", done: true},
              {id: 2, name: "睡覺", done: true},
              {id: 3, name: "編程", done: false},
              {id: 4, name: "寫作", done: false},
              {id: 5, name: "逛街", done: true},
          ]

          map方法

          參數(shù):只接收一個參數(shù),必須是處理數(shù)據(jù)的函數(shù)。

          作用:對數(shù)組成員調(diào)用傳來的參數(shù)函數(shù),進行處理后給出返回值。

          返回值:返回由返回值構(gòu)成的新數(shù)組。

          需求

          寫一個可以更新todo數(shù)組數(shù)據(jù)的函數(shù),例如對todo數(shù)組中id為3的done字段更新為true。

          代碼

          map版本:

          function updateTodo(arr, id, state) {  // arr是數(shù)組,id是要處理的id,state是要更新的狀態(tài)
              return arr.map(item=> {
                  if (item.id===id) return {...item, done: state}  // 若找到指定id,那么更新數(shù)據(jù)
                  else return item  // 若沒找到指定id,返回原值
              })
          }`

          for循環(huán)版本:

          function updateFor(arr, id, state) {
              let newArr=[]
              for (let i=0; i < arr.length; i++) {
                  if (arr[i].id===id) newArr[i]={...arr[i], done: state}
                  else newArr[i]=arr[i]
              }
              return newArr
          }`

          測試

          const newTodo1=updateTodo(todo,3,true)  // 檢查運行結(jié)果可以看到id是3的記錄的狀態(tài)已更新為true
          todo=newTodo1  // 將新內(nèi)容更新到原數(shù)組
          const newTodo2=updateFor(todo,1,false)  // 檢查運行結(jié)果可以看到id是1的記錄的狀態(tài)已更新為false
          todo=newTodo2  // 將新內(nèi)容更新到原數(shù)組`

          filter方法

          參數(shù):只接收一個參數(shù),必須是處理數(shù)據(jù)的函數(shù)。

          作用:對數(shù)組成員調(diào)用傳來的參數(shù)函數(shù),進行處理后給出true或false的返回值。

          返回值:返回由返回值為true的數(shù)組成員構(gòu)成的新數(shù)組。

          需求

          寫一個可以刪除todo數(shù)組指定行的函數(shù),例如將todo數(shù)組中id為3那行數(shù)據(jù)刪除。

          代碼

          filter版本:

          function deleteTodo(arr, id) {  // arr是數(shù)組,id是要處理的id,state是要更新的狀態(tài)
              return arr.filter(item=> {
                  if (item.id===id) return false  // 若找到指定id,那么返回false,表示該行數(shù)據(jù)不要
                  else return true  // 其他行數(shù)據(jù)返回true,表示該行數(shù)據(jù)需要
              })
          }`

          for循環(huán)版本:

          function deleteFor(arr, id) {
              let newArr=[]
              for (let i of arr) {
                  if (i.id !==id) newArr.push(i)
              }
              return newArr
          }`

          測試

          const newTodo1=deleteTodo(todo,3)  // 檢查運行結(jié)果可以看到id是3的記錄不存在
          todo=newTodo1  // 將新內(nèi)容更新到原數(shù)組
          const newTodo2=deleteFor(todo,4)  // 檢查運行結(jié)果可以看到id是4的記錄不存在
          todo=newTodo2  // 將新內(nèi)容更新到原數(shù)組

          reduce方法

          參數(shù):接收兩個參數(shù),第一個必須是處理數(shù)據(jù)的函數(shù),第二個是初始值(數(shù)字型)。注意:該參數(shù)函數(shù)可以接收到4個參數(shù),第一個參數(shù)是累加值,第二個參數(shù)是當前的數(shù)組成員,第三個參數(shù)是索引,第四個參數(shù)是數(shù)組,一般后2個可忽略。

          作用:對數(shù)組成員調(diào)用傳來的參數(shù)函數(shù),進行處理后給出數(shù)字,然后將該數(shù)字累加到累加值上。

          返回值:返回累加值。

          需求

          寫一個可以統(tǒng)計todo數(shù)組中done為true的記錄數(shù)量的函數(shù)。

          代碼

          reduce版本:

          function countTodo(arr) {
              return arr.reduce((total,item)=> total+(item.done?1:0),0)
          }

          for循環(huán)版本:

          function countFor(arr) {
              let count=0
              for (let i of arr) {
                  if (i.done) count++
              }
              return count
          }

          測試

          const count1=countTodo(todo)  // 檢查運行結(jié)果可以看到統(tǒng)計結(jié)果是3
          const count2=countFor(todo)  // 檢查運行結(jié)果可以看到統(tǒng)計結(jié)果也是3

          結(jié)束語

          寫完了,希望對還沒徹底掌握map、filter、reduce這3個高階函數(shù)用法的朋友能有所幫助。請參考數(shù)據(jù)、需求和代碼,嘗試理解,自己敲一遍,然后嘗試自己寫一下。這樣就能徹底掌握map、filter、reduce這3個常用的高階函數(shù)了。

          請注意:這3個函數(shù)底層有優(yōu)化,用它們比自己寫循環(huán)的運行效率要高,代碼也更簡潔。它們都是前端程序員處理數(shù)據(jù)時經(jīng)常要用到的!


          主站蜘蛛池模板: 国产精品久久一区二区三区 | 日韩一区二区在线观看视频| 国产精品视频一区| 亚洲美女视频一区二区三区| 97一区二区三区四区久久| 伊人久久精品一区二区三区| 国产在线一区观看| jizz免费一区二区三区| 无码一区二区三区老色鬼| 在线精品视频一区二区| 日韩精品中文字幕视频一区| 国产美女视频一区| 蜜臀AV一区二区| 国产视频一区在线播放| 中日av乱码一区二区三区乱码| 久久se精品一区二区国产| 日本一道高清一区二区三区| 变态调教一区二区三区| 久久人妻内射无码一区三区| 日韩精品一区二区三区中文3d | 国偷自产一区二区免费视频| 无码av人妻一区二区三区四区| 国产一区二区视频免费| 久久免费精品一区二区| 国产成人久久一区二区不卡三区| 一区二区三区免费看| 日韩一区二区在线观看视频| 精品女同一区二区| 人妻激情偷乱视频一区二区三区| 国产精品久久亚洲一区二区| 国产成人无码一区二区在线播放| 日韩一区二区三区免费体验| 夜夜添无码试看一区二区三区| 国模视频一区二区| 国产亚洲自拍一区| 成人免费视频一区二区三区| 无码国产精品一区二区免费16| 国产一区二区三区日韩精品| 日韩精品无码免费一区二区三区| 无码少妇一区二区浪潮av| 亚洲AV无码一区二区三区性色 |