值和引用
js中的赋值方式分为值传递和引用传递
值传递
赋值过程只传递值,后者的变化不会影响前者
- number -> 1
- string -> 'a'
- boolean -> true
let x = 'x'
let y = x
y = 'y'
console.log(x) // x
console.log(y) // y
引用传递
赋值过程传递的是地址,后者的变化会更改前者
- object -> {} , []
let x = { name: 'x' }
let y = x
y.name = 'y'
console.log(x) // {name:'y'}
console.log(y) // {name:'y'}
浅拷贝
- Object.assign() 完成浅拷贝
let x = { name: 'x' }
let y = Object.assign({}, x)
y.name = 'y'
console.log(x) // {name:'x'}
console.log(y) // {name:'y'}
- 当对象的属性也为引用传递类型时,则需要用 深拷贝
let x = { name: 'x', other: { age: 12 } }
let y = Object.assign({}, x)
y.name = 'y'
y.other.age = 100
console.log(x) // {name:'x',other:{age:100}}
console.log(y) // {name:'y',other:{age:100}}
深拷贝
JSON
- 使用
JSON.parse(JSON.stringify(x))
let x = { name: 'x', other: { age: 12 } }
let y = JSON.parse(JSON.stringify(x))
y.name = 'y'
y.other.age = 100
console.log(x) // {name:'x',other:{age:12}}
console.log(y) // {name:'y',other:{age:100}}
使用JSON的方法,无法转换function
let x = { name: 'x', other: { age: 12 }, getName() { } }
let y = JSON.parse(JSON.stringify(x))
y.name = 'y'
y.other.age = 100
console.log(x) // {name: "x", other: {age:12}, getName: ƒ}
console.log(y) // {name: "y", other: {age:100}}
Lodash
- 使用第三方工具类 完成深拷贝
let x = { name: 'x', other: { age: 12 }, getName() { } }
let y = _.cloneDeep(x)
y.name = 'y'
y.other.age = 100
console.log(x) // {name: "x", other: {age:12}, getName: ƒ}
console.log(y) // {name: "x", other: {age:100}, getName: ƒ}