JavaScript中怎么實(shí)現(xiàn)數(shù)組拷貝

這期內(nèi)容當(dāng)中小編將會(huì)給大家?guī)?lái)有關(guān)JavaScript中怎么實(shí)現(xiàn)數(shù)組拷貝,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

我們提供的服務(wù)有:網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、博野ssl等。為上千企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的博野網(wǎng)站制作公司

1、擴(kuò)展運(yùn)算符(淺拷貝)

自從ES6出現(xiàn)以來(lái),這已經(jīng)成為最流行的方法。它是一個(gè)很簡(jiǎn)單的語(yǔ)法,但是當(dāng)你在使用類(lèi)似于React和Redux這類(lèi)庫(kù)時(shí),你會(huì)發(fā)現(xiàn)它是非常非常有用的。

numbers = [1, 2, 3];
numbersCopy = [...numbers];
這個(gè)方法不能有效的拷貝多維數(shù)組。數(shù)組/對(duì)象值的拷貝是通過(guò)引用而不是值復(fù)制。
// numbersCopy.push(4);
console.log(numbers, numbersCopy);
// [1, 2, 3] and [1, 2, 3, 4]
// 只修改了我們希望修改的,原數(shù)組不受影響
// nestedNumbers = [[1], [2]];
numbersCopy = [...nestedNumbers];
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1, 300], [2]]
// [[1, 300], [2]]
// 由于公用引用,所以兩個(gè)數(shù)組都被修改了,這是我們不希望的

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

考慮到函數(shù)式編程變得越來(lái)越流行,我認(rèn)為這種方法可能是最不受歡迎的。

numbers = [1, 2, 3];
numbersCopy = [];
for (i = 0; i < numbers.length; i++) {
 numbersCopy[i] = numbers[i];
}
這個(gè)方法不能有效的拷貝多維數(shù)組。因?yàn)槲覀兪褂玫氖?運(yùn)算符,它在處理數(shù)組/對(duì)象值的拷貝時(shí)通過(guò)引用而不是值復(fù)制。
// 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);
// [[1, 300], [2]]
// [[1, 300], [2]]
// 由于公用引用,所以兩個(gè)數(shù)組都被修改了,這是我們不希望的

3、while()循環(huán)(淺拷貝)和for() 類(lèi)似。

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

4、Array.map(淺拷貝)

上面的for和while都是很“古老”的方式,讓我們繼續(xù)回到當(dāng)前,我們會(huì)發(fā)現(xiàn)map方法。map源于數(shù)學(xué),是將一個(gè)集合轉(zhuǎn)換成另一種集合,同時(shí)保留結(jié)構(gòu)的概念。

在英語(yǔ)中,它意味著Array.map 每次返回相同長(zhǎng)度的數(shù)組。

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

當(dāng)我們使用map方法時(shí),需要給出一個(gè)callback函數(shù)用于處理當(dāng)前的數(shù)組,并返回一個(gè)新的數(shù)組元素。

和拷貝數(shù)組有什么關(guān)系呢?

當(dāng)我們想要復(fù)制一個(gè)數(shù)組的時(shí)候,只需要在map的callback函數(shù)中直接返回原數(shù)組的元素即可。

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

如果你想更數(shù)學(xué)化一點(diǎn),(x) => x叫做恒等式。它返回給定的任何參數(shù)。

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

同樣的,處理對(duì)象和數(shù)組的時(shí)候是引用而不是值復(fù)制。

5、Array.filter(淺拷貝)

Array.filter方法同樣會(huì)返回一個(gè)新數(shù)組,但是并不一定是返回同樣長(zhǎng)度的,這和我們的過(guò)濾條件有關(guān)。

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

當(dāng)我們的過(guò)濾條件總是true時(shí),就可以用來(lái)實(shí)現(xiàn)拷貝。

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

同樣的,處理對(duì)象和數(shù)組的時(shí)候是引用而不是值復(fù)制。

6、Array.reduce(淺拷貝)

其實(shí)用reduce來(lái)拷貝數(shù)組并沒(méi)有展示出它的實(shí)際功能,但是我們還是要將其能夠拷貝數(shù)組的能力說(shuō)一下的

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

reduce() 方法對(duì)數(shù)組中的每個(gè)元素執(zhí)行一個(gè)由您提供的reducer函數(shù),將其結(jié)果匯總為單個(gè)返回值。

上面我們的例子中初始值是一個(gè)空數(shù)組,我們?cè)诒闅v原數(shù)組的時(shí)候來(lái)填充這個(gè)空數(shù)組。該數(shù)組必須要從下一個(gè)迭代函數(shù)的執(zhí)行后被返回出來(lái)。

同樣的,處理對(duì)象和數(shù)組的時(shí)候是引用而不是值復(fù)制。

7、Array.slice(淺拷貝)

slice 方法根據(jù)我們指定的start、end的index從原數(shù)組中返回一個(gè)淺拷貝的數(shù)組。

[1, 2, 3, 4, 5].slice(0, 3);
// [1, 2, 3]
// Starts at index 0, stops at index 3
// 當(dāng)不給定參數(shù)時(shí),就返回了原數(shù)組的拷貝
numbers = [1, 2, 3, 4, 5];
numbersCopy = numbers.slice();
// [1, 2, 3, 4, 5]

同樣的,處理對(duì)象和數(shù)組的時(shí)候是引用而不是值復(fù)制。

8、JSON.parse & JSON.stringify(深拷貝)

JSON.stringify將一個(gè)對(duì)象轉(zhuǎn)成字符串;
JSON.parse將轉(zhuǎn)成的字符串轉(zhuǎn)回對(duì)象。

將它們組合起來(lái)可以將對(duì)象轉(zhuǎn)換成字符串,然后反轉(zhuǎn)這個(gè)過(guò)程來(lái)創(chuàng)建一個(gè)全新的數(shù)據(jù)結(jié)構(gòu)。

nestedNumbers = [[1], [2]];
numbersCopy = JSON.parse(
 JSON.stringify(nestedNumbers)
);
numbersCopy[0].push(300);
console.log(nestedNumbers, numbersCopy);
// [[1], [2]]
// [[1, 300], [2]]
// These two arrays are completely separate!

這個(gè)可以安全地拷貝深度嵌套的對(duì)象/數(shù)組

幾種特殊情況

1、如果obj里面有時(shí)間對(duì)象,則JSON.stringify后再JSON.parse的結(jié)果,時(shí)間將只是字符串的形式。而不是時(shí)間對(duì)象;

var test = {
 name: 'a',
 date: [new Date(1536627600000), new Date(1540047600000)],
};
let b;
b = JSON.parse(JSON.stringify(test))
console.log(b)

2、如果obj里有RegExp、Error對(duì)象,則序列化的結(jié)果將只得到空對(duì)象;

const test = {
 name: 'a',
 date: new RegExp('\\w+'),
};
// debugger
const copyed = JSON.parse(JSON.stringify(test));
test.name = 'test'
console.log('ddd', test, copyed)

3、如果obj里有函數(shù),undefined,則序列化的結(jié)果會(huì)把函數(shù)或 undefined丟失;

const test = {
 name: 'a',
 date: function hehe() {
 console.log('fff')
 },
};
// debugger
const copyed = JSON.parse(JSON.stringify(test));
test.name = 'test'
console.error('ddd', test, copyed)

4、如果obj里有NaN、Infinity和-Infinity,則序列化的結(jié)果會(huì)變成null

5、JSON.stringify()只能序列化對(duì)象的可枚舉的自有屬性,例如 如果obj中的對(duì)象是有構(gòu)造函數(shù)生成的, 則使用JSON.parse(JSON.stringify(obj))深拷貝后,會(huì)丟棄對(duì)象的constructor;

function Person(name) {
 this.name = name;
 console.log(name)
}
const liai = new Person('liai');
const test = {
 name: 'a',
 date: liai,
};
// debugger
const copyed = JSON.parse(JSON.stringify(test));
test.name = 'test'
console.error('ddd', test, copyed)

9、Array.cancat(淺拷貝)

concat將數(shù)組與值或其他數(shù)組進(jìn)行組合。

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

如果我們不指定參數(shù)或者提供一個(gè)空數(shù)組作為參數(shù),就可以進(jìn)行淺拷貝。

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

同樣的,處理對(duì)象和數(shù)組的時(shí)候是引用而不是值復(fù)制。

10、Array.from(淺拷貝)

可以將任何可迭代對(duì)象轉(zhuǎn)換為數(shù)組。給一個(gè)數(shù)組返回一個(gè)淺拷貝。

console.log(Array.from('foo'))
// ['f', 'o', 'o']
numbers = [1, 2, 3];
numbersCopy = Array.from(numbers)
// [1, 2, 3]

上述就是小編為大家分享的JavaScript中怎么實(shí)現(xiàn)數(shù)組拷貝了,如果剛好有類(lèi)似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

分享文章:JavaScript中怎么實(shí)現(xiàn)數(shù)組拷貝
地址分享:http://bm7419.com/article48/jdieep.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、網(wǎng)站內(nèi)鏈、商城網(wǎng)站、網(wǎng)站營(yíng)銷(xiāo)、企業(yè)建站網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)