引入:原始值與引用值的復制
當我們復制原始數據時,如數值、字符串,舉例來說,下面的b相當於開辟了新的空間來放置變量b,並儲存了a的值,所以改變b的值不會影響a的值。
let a=1
let b=a
console.log(a) //1
console.log(b) //1
b=2
console.log(a) //1
console.log(b) //2
而當我們復制引用數據時,如數組、對象,如下:
let person={name:'jack'}
let student=person
console.log(person) //{name:'jack'}
console.log(student) //{name:'jack'}
console.log(person==student)//true
//改變數據
student.name='sean'
console.log(student) //{name:'sean'}
console.log(person) //{name:'sean'}
console.log(person==student)//true
為什么person也跟着變了呢?
這是因為person指向的是{name:'jack'}
對象,student只是單純的復制了一個指向,也就是同樣地指向了{name:'jack'}
對象,可以理解為{name:'jack'}
對象是它們兩者共享的區域。所以當student改變name的時候,並不是改變本身,而改變了{name:'jack'}
這個共享區域的name,而此時person 的指向沒有變化,所以person的name也隨之變化了。
這往往不是我們希望得到的結果。那如何復制了引用類型后,不會改變原來的值呢?那就要深度拷貝
總結:深度拷貝的方法
對象
-
方法一:
Object.assign({},origin)
let person={name:'jack'} let student=Object.assign({},person)
只對一級屬性的對象有效
-
方法二:
JSON.parse(JSON.stringify(origin))
let person={name:'jack'} let student=JSON.parse(JSON.stringify(person))
數組
-
方法一:
[].concat(origin)
let animals=['老虎','獅子'] let zoo=[].concat(animals)
對於一維數組是深拷貝,對一維以上的數組是引用
-
方法二:
origin.slice()
let animals=['老虎','獅子'] let zoo=animals.slice()
對於一維數組是深拷貝,對一維以上的數組是引用