js变量分为值类型和引用类型,数组属于引用类型。
值类型
var a=100;
var b=a;
a=200;
console.log(b);//100 **值类型的特点:它每个变量都能存储各自的值,不会相互影响**
引用类型
var a={age:20};
var b=a;
b.age=21;
console.log(a.age);//21 **引用类型的特点:不同变量之间的值,会相互影响**`
值类型和引用类型的特点
特点:从内存中来说,值类型是把每一个值都存到变量内存的位置,比如a存了100,把b赋值给a,b的位置又存了100这个数字,a的位置把100改成200,b的位置等于100,还是100,所以它不会相互影响。
引用类型他不一样,引用类型是把a赋值成一个对象,这个对象存在另一个地方,a内存的位置是通过一个指针指向这个对象的地方,把b赋值成a的时候,其实是定义了一个b,b的指针又指向了那个对象的位置,所以这个age=20这个对象只有一份,a和b同时指向了这个对象而已,所以说当执行第三行b.age=21的时候,那个age的值已经改成了21,所以a也是指向这个对象,所以说a.age也是21。
引用类型为什么要这样做,而不是直接拷贝也存储一份?
引用类型可以无限制扩展属性,比如现在它有个age属性,我们也可以加name属性啊,grade属性啊,等等等等很多属性,属性加多了之后,会出现内存占用比较多的问题。在值类型中a=100,把b赋值成a,相当于把100又重新拷贝了一份存下,没有关系,因为100不会占用很多内存。如果这个地方把a赋值成一个对象,但是它又特别大,b再赋值成a,b也拷贝复制一份,他就会占很大的空间,这是不合理的,所以说为了让内存共用空间,才会出现引用类型这种方式。
深拷贝
let arr=[{
name:'111',
title:'111',
children:[{
name:'111-1',
title:'111-1'
},{
name:'111-2',
title:'111-2'
}]
}]
let newArr=arr.slice(0)
for(let i of newArr){
var arr2 = i.children.filter((item2) => {
return item2.name === '111-1'
})
i.children=arr2
}
console.log('arr',arr)
console.log('newArr',newArr)
根据上面打印可以看到,深拷贝之后还是改变了arr的值,这个时候我们可以用JSON.parse和JSON.stringify来实现。
let arr=[{
name:'111',
title:'111',
children:[{
name:'111-1',
title:'111-1'
},{
name:'111-2',
title:'111-2'
}]
}]
let newArr=JSON.parse(JSON.stringify(arr))
for(let i of newArr){
var arr2 = i.children.filter((item2) => {
return item2.name === '111-1'
})
i.children=arr2
}
console.log('arr',arr)
console.log('newArr',newArr)
这样arr就不会受影响了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。