Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美成人在线免费视频,日本一区二区三区国产,视频一区二区在线播放

          整合營銷服務商

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

          免費咨詢熱線:

          JavaScript中數(shù)組的克隆

          JavaScript中數(shù)組的克隆

          展運算符...(淺拷貝

          這是在ES6中出現(xiàn)的新的運算符,自從出現(xiàn)以來,它已經成為最受歡迎的方法之一,它的語法實在是太簡潔

          numbers=[1, 2, 3];
          numbersCopy=[...numbers];
          

          注意:它不能安全的復制多維數(shù)組,數(shù)組/對象是通過引用復制而不是通過值復制

          正例:

          numbersCopy.push(4);
          console.log(numbers, numbersCopy);
          // [1, 2, 3] and [1, 2, 3, 4]
          

          反例:

          nestedNumbers=[[1], [2]];
          numbersCopy=[...nestedNumbers];
          numbersCopy[0].push(300);
          console.log(nestedNumbers, numbersCopy);
          // [[1, 300], [2]]
          // [[1, 300], [2]]
          

          for循環(huán)(淺拷貝)

          由于函數(shù)式編程的流行,現(xiàn)在應該用的比較少了

          numbers=[1, 2, 3];
          numbersCopy=[];
          for (i=0; i < numbers.length; i++) {
           numbersCopy[i]=numbers[i];
          }
          

          注意:它也不能安全地復制多維數(shù)組。因為使用=運算符,因此它將通過引用而不是值來分配對象/數(shù)組。

          正例:

          numbersCopy.push(4);
          console.log(numbers, numbersCopy);
          // [1, 2, 3] and [1, 2, 3, 4]
          

          反例:

          nestedNumbers=[[1], [2]];
          numbersCopy=[];
          for (i=0; i < nestedNumbers.length; i++) {
           numbersCopy[i]=nestedNumbers[i];
          }
          numbersCopy[0].push(300);
          console.log(nestedNumbers, numbersCopy);
          

          while循環(huán)(淺拷貝)

          和for循環(huán)類似

          numbers=[1, 2, 3];
          numbersCopy=[];
          i=-1;
          while (++i < numbers.length) {
           numbersCopy[i]=numbers[i];
          }
          

          注意:它也通過引用而不是按分配對象/數(shù)組。

          正例:

          numbersCopy.push(4);
          console.log(numbers, numbersCopy);
          // [1, 2, 3] and [1, 2, 3, 4]
          

          反例:

          nestedNumbers=[[1], [2]];
          numbersCopy=[];
          i=-1;
          while (++i < nestedNumbers.length) {
           numbersCopy[i]=nestedNumbers[i];
          }
          numbersCopy[0].push(300);
          console.log(nestedNumbers, numbersCopy);
          // [[1, 300], [2]]
          // [[1, 300], [2]]
          

          Array.map(淺拷貝)

          map會將數(shù)組轉換成為另一個數(shù)組又同時保留結構的方法

          numbers=[1, 2, 3];
          double=(x)=> x * 2;
          numbers.map(double);
          

          復制數(shù)組就更簡單了

          numbers=[1, 2, 3];
          numbersCopy=numbers.map((x)=> x);
          

          注意:它同樣也通過引用而不是按值分配對象/數(shù)組。

          Array.filter(淺拷貝)

          和map一樣,接受一個函數(shù)組作為參數(shù),但是它會通過傳遞的函數(shù)過濾和篩選,這樣不能保證得到數(shù)組長度不變,比如篩選出數(shù)組中的偶數(shù)

          [1, 2, 3].filter((x)=> x % 2===0)
          // [2]
          

          復制數(shù)組

          numbers=[1, 2, 3];
          numbersCopy=numbers.filter(()=> true);
          

          注意:它同樣也通過引用而不是按值分配對象/數(shù)組。

          Array.reduce(淺拷貝)

          reduce 在循環(huán)列表時轉換初始值

          numbers=[1, 2, 3];
          numbersCopy=numbers.reduce((newArray, element)=> {
           newArray.push(element);
           return newArray;
          }, []);
          

          注意:它同樣也通過引用而不是按值分配對象/數(shù)組。

          Array.slice(淺拷貝)

          slice需要你傳遞開始索引和結束索引

          [1, 2, 3, 4, 5].slice(0, 3);
          // [1, 2, 3]
          // 0到3索引,得到1,2,3,不包括4
          

          如果只想復制,不需要傳遞任何參數(shù)即可

          numbers=[1, 2, 3, 4, 5];
          numbersCopy=numbers.slice();
          // [1, 2, 3, 4, 5]
          

          注意:它同樣也通過引用而不是按值分配對象/數(shù)組。

          JSON.parse和JSON.stringify(深層拷貝)

          • JSON.stringify 將對象轉換為字符串。
          • JSON.parse 將字符串轉換為對象。

          組合它們可以將對象轉換為字符串,然后反轉該過程可以創(chuàng)建全新的數(shù)據(jù)結構。

          nestedNumbers=[[1], [2]];
          numbersCopy=JSON.parse(
           JSON.stringify(nestedNumbers)
          );
          numbersCopy[0].push(300);
          console.log(nestedNumbers, numbersCopy);
          // [[1], [2]]
          // [[1, 300], [2]]
          // 兩個數(shù)組是分開的
          

          注意:它是安全的復制方法

          Array.concat(淺拷貝)

          concat是數(shù)組之間相連接,例如

          [1, 2, 3].concat(4); // [1, 2, 3, 4]
          [1, 2, 3].concat([4, 5]); // [1, 2, 3, 4, 5]
          

          如果只是單純的復制,那你可以不傳遞任何參數(shù)或者傳遞一個空數(shù)組即可

          [1, 2, 3].concat(); // [1, 2, 3]
          [1, 2, 3].concat([]); // [1, 2, 3]
          

          注意:它同樣也通過引用而不是按值分配對象/數(shù)組。

          Array.from(淺拷貝)

          可以將任何可迭代對象轉換為數(shù)組,如下

          numbers=[1, 2, 3];
          numbersCopy=Array.from(numbers)
          // [1, 2, 3]
          

          注意:它同樣也通過引用而不是按值分配對象/數(shù)組。

          總結

          本文著重探討的是數(shù)組的復制,這些方法都可以用來做數(shù)組的拷貝,各有好壞,其實還有其他的一些方法來完成數(shù)組的復制,本文就介紹到這,如果對你有幫助,請點個關注吧!

          在前端開發(fā)的浩瀚海洋中,JavaScript猶如一盞明燈,照亮了網頁交互的每一個角落。作為現(xiàn)代Web開發(fā)不可或缺的一部分,掌握JavaScript的核心概念是每個前端工程師的基本功。本文旨在深入解析JavaScript中的幾個關鍵點——二維數(shù)組的操作、引用類型的特性以及深克隆與淺克隆的區(qū)別,通過理論結合實踐,幫助初學者構建堅實的基礎。

          技術概述

          二維數(shù)組

          二維數(shù)組是數(shù)組元素本身也是數(shù)組的數(shù)據(jù)結構,常用于模擬表格或矩陣。它們在處理網格布局、游戲地圖等場景時尤為有用。

          示例代碼:

          let matrix=[
            [1, 2, 3],
            [4, 5, 6],
            [7, 8, 9]
          ];
          console.log(matrix[1][2]); // 輸出 6
          

          引用類型

          JavaScript中的對象、數(shù)組、函數(shù)等都屬于引用類型。它們存儲的是指向數(shù)據(jù)的引用,而非數(shù)據(jù)本身,這意味著多個變量可以引用同一個對象。

          示例代碼:

          let obj1={ value: 10 };
          let obj2=obj1;
          obj2.value=20;
          console.log(obj1.value); // 輸出 20
          

          深克隆與淺克隆

          克隆是在不改變原對象的情況下復制對象的過程。淺克隆僅復制對象的第一層屬性,而深克隆會遞歸復制所有層級的屬性。

          示例代碼:

          function shallowClone(obj) {
            return Object.assign({}, obj);
          }
          
          function deepClone(obj) {
            return JSON.parse(JSON.stringify(obj));
          }
          

          技術細節(jié)

          二維數(shù)組

          • 訪問與修改:可以通過雙層索引訪問或修改元素。
          • 遍歷:使用嵌套循環(huán)來遍歷整個數(shù)組。

          引用類型

          • 共享與更新:引用類型的變化會影響所有引用它的變量。
          • 內存管理:理解垃圾回收機制對管理引用類型非常重要。

          克隆技巧

          • 淺克隆:適用于不需要復制深層屬性的情況。
          • 深克隆:確保完全獨立的副本,但可能在大型對象上消耗更多資源。

          實戰(zhàn)應用

          二維數(shù)組的應用場景

          考慮一個游戲開發(fā)場景,二維數(shù)組可以用來表示游戲地圖,其中每個元素代表地圖上的一個位置。


          示例代碼:

          let gameMap=[
            ['water', 'land', 'land'],
            ['land', 'forest', 'mountain'],
            ['mountain', 'water', 'land']
          ];
          

          引用類型的使用

          在事件監(jiān)聽器中傳遞對象時,利用引用類型可以實時反映對象狀態(tài)的變化。

          示例代碼:

          let data={ count: 0 };
          
          document.getElementById('myButton').addEventListener('click', function() {
            data.count++;
            console.log(data.count);
          });
          

          克隆技巧的實踐

          在需要保持數(shù)據(jù)原始狀態(tài)不變的場景下,如表單的初始值保存,使用深克隆可以創(chuàng)建一份完全獨立的數(shù)據(jù)副本。


          示例代碼:

          let originalFormValues={ name: 'John', age: 30 };
          let formBackup=deepClone(originalFormValues);
          

          優(yōu)化與改進

          避免不必要的深克隆

          深克隆會消耗更多的計算資源,對于復雜的對象,應評估是否真的需要復制每一層。

          選擇合適的克隆方法

          對于包含函數(shù)或循環(huán)引用的對象,使用JSON.parseJSON.stringify進行深克隆可能失敗,這時需要尋找更專業(yè)的克隆庫或自定義克隆函數(shù)。

          常見問題

          如何判斷一個變量是引用類型?

          可以使用typeof檢查,但更準確的方法是使用Object.prototype.toString.call()

          示例代碼:

          function isObject(value) {
            return Object.prototype.toString.call(value)==='[object Object]';
          }
          

          如何避免引用類型引起的副作用?

          確保在函數(shù)內部使用局部變量,避免直接修改傳入的引用類型參數(shù)。

          總結與展望

          掌握JavaScript中的二維數(shù)組、引用類型和克隆技巧是構建高效、健壯的前端應用程序的關鍵。隨著Web技術的不斷演進,這些基礎知識將為開發(fā)者提供強大的工具箱,應對未來可能出現(xiàn)的各種挑戰(zhàn)。繼續(xù)深化你的JavaScript技能,探索更多高級主題,如異步編程、模塊化設計和性能優(yōu)化,將使你在前端開發(fā)領域更加游刃有余。


          意味著,當您嘗試使用 const newArray=oldArray 復制它時,它將復制對原始數(shù)組的引用而不是復制值。

          const beers=['', '', ''];
          const beersCopy=beers;
          console.log(beers===beersCopy);
          // The console output will be true, because it's pointing to the exact value in memory.
          

          淺拷貝數(shù)組
          當拷貝或克隆數(shù)組時,值的數(shù)據(jù)類型是決定使用何種方法的關鍵。

          如果您的數(shù)組僅包含原始不可變值(數(shù)字、布爾值、字符串等),您可以使用以下方法。

          • push
          • … (傳播)
          • .slice -Array.from
          • _.clone (lodash) .push() 一種經典的數(shù)組方法,也是最明顯的方法,基本上循環(huán)原始數(shù)組并使用 push() 方法將原始數(shù)組中的元素推送到新數(shù)組中。

          我們簡單地遍歷原始數(shù)組并將每個元素推送到新數(shù)組。

          const arr=[1, 2, 3];
          const newArr=[];
          for (let i=0; i < arr.length; i++) {
            newArr.push(arr[i]);
          }
          

          …(展開)
          展開運算符是最快的方法之一,是在 ES6 中引入的。它簡潔明了,是一種本地方法(對不起 lodash)。

          const arr=[1, 2, 3];
          const newArr=[...arr];
          .slice()
          

          slice() 方法將數(shù)組的一部分的淺拷貝返回到從頭到尾選擇的新數(shù)組對象中 arr.slice([start[, end]])。原始數(shù)組不會被修改。這是復制數(shù)組的最快方法。

          const arr=[1, 2, 3];
          const newArr=arr.slice();
          Array.from
          

          Array.from() 靜態(tài)方法從類數(shù)組或可迭代對象(Map 或 Set)創(chuàng)建一個新的淺拷貝 Array 實例。

          它還采用可選的映射函數(shù)作為第二個參數(shù) Array.from(arrayLike [, mapFn [, thisArg]])。

          const arr=[1, 2, 3];
          const newArr=Array.from(arr);
          _.clone()
          

          lodash 的 _.clone(value) 方法創(chuàng)建了一個值的淺克隆。它表現(xiàn)良好,如果您已經在您的應用程序中使用 lodash,它是一個可行的選擇。

          // import lodash
          const _=require('lodash');
          const arr=[1, 2, 3];
          const newArr=_.clone(arr);
          Deep Copy Arrays
          

          上面的所有方法都會創(chuàng)建數(shù)組的淺表副本。如果您將對象作為數(shù)組項,并且嘗試進行淺拷貝,則將復制實際數(shù)組,但底層對象將通過引用傳遞給新數(shù)組。

          讓我們通過一個代碼示例來看一下這個問題。

          const arr=[
            {
              name: 'mario',
              food: 'pizza',
            },
            {
              name: 'luigi',
              food: 'spaghetti',
            },
          ];
          const arrCopy=[...arr];
          console.log(arr===arrCopy);
          

          // 這將返回 false,因為數(shù)組已被復制(淺復制),內存中的新引用。
          console.log(arr[0]===arrCopy[0]);
          // 這將返回 true,因為引用指向內存中的相同位置。
          有幾種方法可以創(chuàng)建深度克隆。

          jQuery.extend()
          _.clonedeep()
          JSON (stringify/parse)
          jQuery.extend()
          如果您仍在項目中使用 jQuery,則可以使用 jQuery 的擴展方法。

          const arr=[
            {
              name: 'mario',
              food: 'pizza',
            },
            {
              name: 'luigi',
              food: 'spaghetti',
            },
          ];
          const arrCopy=jQuery.extend(true, [], arr);
          console.log(arr===arrCopy);
          // This will return false, because the array has been copied (new reference in memory).
          console.log(arr[0]===arrCopy[0]);
          // This will return false, because the reference points to a new one in memory.
          _.cloneDeep()
          

          來自 Lodash 的方法 _.cloneDeep(value) 做的事情與 _.clone() 完全相同,除了它遞歸地克隆數(shù)組中的所有內容。

          const arr=[
            {
              name: 'mario',
              food: 'pizza',
            },
            {
              name: 'luigi',
              food: 'spaghetti',
            },
          ];
          // import lodash
          const _=require('lodash');
          const arrCopy=_.cloneDeep(arr);
          console.log(arr===arrCopy);
          // This will return false, because the array has been copied (new reference in memory).
          console.log(arr[0]===arrCopy[0]);
          // This will return false, because the reference points to a new one in memory.
          

          JSON 方法
          JavaScript 提供了用于序列化和反序列化的原生方法,基本上是將大多數(shù)數(shù)據(jù)類型轉換為 JSON 字符串,然后將有效的 JSON 字符串轉換為對象。

          它可以這樣使用:

          const arr=[
            {
              name: 'mario',
              food: 'pizza',
            },
            {
              name: 'luigi',
              food: 'spaghetti',
            },
          ];
          const arrCopy=JSON.parse(JSON.stringify(arr));
          console.log(arr===arrCopy);
          // This will return false, because the array has been copied (new reference in memory).
          console.log(arr[0]===arrCopy[0]);
          // This will return false, because the reference points to a new one in memory.
          

          使用這種方法有一些優(yōu)點和缺點。一個優(yōu)點是它不需要像 Lodash 這樣的第三方庫。缺點是提供的數(shù)組數(shù)據(jù)需要可序列化,通過 JSON 進行序列化和反序列化需要一些時間,因此這不是最快的方法。


          主站蜘蛛池模板: 日韩电影一区二区三区| 无码人妻一区二区三区兔费| 色窝窝无码一区二区三区成人网站 | 日韩熟女精品一区二区三区| 午夜DV内射一区二区| 久久精品中文字幕一区| 日本一区中文字幕日本一二三区视频| 色妞AV永久一区二区国产AV| 国产AV天堂无码一区二区三区| 午夜福利无码一区二区| 日韩中文字幕精品免费一区| 亚洲一区二区三区精品视频| 人妻体内射精一区二区三区| 无码精品一区二区三区在线| 亚洲爆乳精品无码一区二区三区| 亚洲日韩精品一区二区三区| 国偷自产一区二区免费视频| 无码人妻AⅤ一区二区三区| 精品日产一区二区三区手机| 久久精品无码一区二区三区| 一区二区三区人妻无码| 亚洲中文字幕无码一区| 亚洲国产精品一区二区久久hs| 久草新视频一区二区三区| 久久99精品波多结衣一区| 人妻体内射精一区二区三区| 亚洲色精品VR一区区三区| 国产精品亚洲午夜一区二区三区| 精品不卡一区二区| 国产一区二区在线观看| 国产精品亚洲专一区二区三区 | 一区二区三区亚洲视频| 亚洲福利视频一区二区| 一本大道东京热无码一区| 久久国产午夜一区二区福利| 亚洲午夜一区二区电影院| 久久久国产精品无码一区二区三区| 久热国产精品视频一区二区三区| 国产免费av一区二区三区| 91福利国产在线观看一区二区| 无码少妇一区二区性色AV|