JavaScript中引用vs復(fù)制示例詳析
前言
好像一般很少人講到j(luò)s中的引用和復(fù)制,不過弄清楚這個概念可以幫助理解很多東西
先講一下很基礎(chǔ)的東西,看看js中幾種數(shù)據(jù)類型分別傳的什么
引用:對象、數(shù)組、函數(shù)
復(fù)制:數(shù)字、布爾
字符串單獨說明,因為它的特殊性,無法確定是傳遞引用還是復(fù)制數(shù)值(因為字符串的值是沒法改變的,所以糾結(jié)這個問題也是沒意義的)但是用于比較的時候顯然是屬于傳值比較
下面來一起看看詳細的介紹吧
首先我們看下面這個例子:
let age = 18; let age2 = age; console.log(age, age2);
我們會得到以下的值:
18 18
這個相信大家都能很好理解。
那么如果我們改變 age 的值呢?輸出會有什么變化?
age = 20; console.log(age, age2);
我們會得到:
20 18
看到這里大家就奇怪了,上面的結(jié)果都很正常啊。
但在 JavaScript 中是有例外的,對于普通數(shù)據(jù)類型如 integer,string,boolean 可以通過 = 來復(fù)制這個變量,但對于 array 和 object 數(shù)據(jù)類型,= 只能起到引用的效果。
大家可以看下面這個例子:
let arr = ['wes', 'bob', 'faker']; let arr2 = arr; console.log(arr2, arr); arr[2] = 'dean'; console.log(arr2, arr);
得到的結(jié)果是:
["wes", "bob", "faker"] ["wes", "bob", "faker"]
["wes", "bob", "dean"] ["wes", "bob", "dean"]
我們會發(fā)現(xiàn)隨著 arr 的改變,arr2 也會跟著改變。
說明 arr2 并沒有復(fù)制 arr 的值,只是引用了它,它們都指向同一個內(nèi)存中的值。
object 也是一樣的:
let obj = { age: 19, name: 'like', last: 'jam' }; let obj2 = obj; console.log(obj, obj2); obj.age = 50; console.log(obj, obj2);
得到的結(jié)果是:
{age: 19, name: "like", last: "jam"} {age: 19, name: "like", last: "jam"}
{age: 50, name: "like", last: "jam"} {age: 50, name: "like", last: "jam"}
那么如何復(fù)制 array 和 object 呢?
復(fù)制 array 的方法:
方法1:
let arr2 = [].concat(arr);
方法2:
let arr2 = arr.slice();
方法3:
let arr2 = Array.from(arr);
方法4:
let arr2 = [...arr];
一般我們比較常用的是方法3和方法4,方法1和方法2比較取巧,但都是可以達到復(fù)制 array 的目的的。
ps: [...arr] 是 ES6 中的方法。
復(fù)制 object 的方法:
方法1:
let obj2 = Object.assign({}, obj);
方法2:
let obj2 = {...obj};
方法1和方法2都有個缺點,它們只會復(fù)制對象的第一層。
看下面這個例子:
let obj = { number: 12, name: { first: 'bob', last: 'evil' } }; let obj2 = Object.assign({}, obj); obj.number = 50; console.log(obj, obj2);
我們會得到下面的結(jié)果:
obj = {
number: 50,
name: {
first: 'bob',
last: 'evil'
}
}obj2 = {
number: 12,
name: {
first: 'bob',
last: 'evil'
}
}
但如果我們改變第二層的值:
obj.name.first = 'sam'; console.log(obj, obj2);
obj = {
number: 50,
name: {
first: 'sam',
last: 'evil'
}
}obj2 = {
number: 12,
name: {
first: 'sam',
last: 'evil'
}
}
我們發(fā)現(xiàn)對象第二層依舊是引用的,并沒有實現(xiàn)復(fù)制。
那么怎么復(fù)制一個完整的 object 呢?
最簡單的方法就是使用第三方函數(shù)庫 lodash ,它提供了 clone 和 deepclone 完全可以滿足日常的需求。
object 的復(fù)制因為要考慮到很多因素,我會另開一篇,專門整理。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
利用jsPDF實現(xiàn)將圖片轉(zhuǎn)為pdf
這篇文章主要為大家詳細介紹了如何利用jsPDF實現(xiàn)將圖片轉(zhuǎn)為pdf的功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起了解一下2023-08-08微信公眾號中的JSSDK接入及invalid signature等常見錯誤問題分析(全面解析)
這篇文章主要介紹了微信公眾號中的JSSDK接入及invalid signature等常見錯誤問題分析(全面解析),需要的朋友可以參考下2020-04-04JavaScript數(shù)據(jù)結(jié)構(gòu)學(xué)習(xí)之數(shù)組、棧與隊列
這篇文章主要給大家介紹了JavaScript數(shù)據(jù)結(jié)構(gòu)之數(shù)組、棧與隊列的相關(guān)資料,文中對數(shù)組、棧與隊列的使用方法進行了詳細的總結(jié),相信對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-05-05JS獲取CSS樣式(style/getComputedStyle/currentStyle)
這篇文章主要為大家介紹了JS獲取CSS樣式的方法,介紹了CSS樣式的三種分類情況,對獲取樣式做一個簡單的封裝,感興趣的小伙伴們可以參考一下2016-01-01Bootstrap框架的學(xué)習(xí)教程詳解(二)
Bootstrap,來自 Twitter,是目前最受歡迎的前端框架。本文給大家介紹Bootstrap框架的學(xué)習(xí)教程詳解,對bootstrap框架感興趣的朋友跟著小編一起學(xué)習(xí)吧2016-10-10JS基于MSClass和setInterval實現(xiàn)ajax定時采集信息并滾動顯示的方法
這篇文章主要介紹了JS基于MSClass和setInterval實現(xiàn)ajax定時采集信息并滾動顯示的方法,涉及JavaScript頁面元素定時滾動操作及ajax調(diào)用實現(xiàn)技巧,需要的朋友可以參考下2016-04-04