1、数据类型

  首先JS分为基础类型和引用类型两种数据类型,基础数据类型赋值时是【传值】,而引用数据类型赋值时是【传址】,所以引用数据类型赋值时新旧值会相互影响,称之浅拷贝。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

  基础类型:number、string、boolean、null、undefined、symbol

  引用类型:Object(Array,Date,RegExp,Function)

  它们有个区别 —— 保存位置不同。基本数据类型保存在栈内存中;引用数据类型保存在堆内存中,然后在栈内存中保存了一个对堆内存中实际对象的引用,即数据在堆内存中的地址。

为什么基本数据类型保存在栈中,而引用数据类型保存在堆中?
1)堆比栈大,栈比堆速度快;
2)基本数据类型比较稳定,而且相对来说占用的内存小;
3)引用数据类型大小是动态的,而且是无限的,引用值的大小会改变,不能把它放在栈中,否则会降低变量查找的速度,因此放在变量栈空间的值是该对象存储在堆中的地址,地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响;
4)堆内存是无序存储,可以根据引用直接获取;

2、浅拷贝与深拷贝

  浅拷贝和深拷贝都只针对于引用数据类型,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,新旧对象改变时相互影响;但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

3、造成浅拷贝的情况

1)引用类型赋值

var obj ={a:1,b:2,c:3};
var obj1= obj;
obj1.a=5;
console.log(obj); //{a: 5, b: 2, c: 3}
console.log(obj1); //{a: 5, b: 2, c: 3}

obj.b=6;
console.log(obj); //{a: 5, b: 6, c: 3}
console.log(obj1); //{a: 5, b: 6, c: 3}

2)对象作为函数参数传递

var obj ={a:1,b:2,c:3};
fn=(obj)=>{
   var obj2= obj;
   obj2.a=5;
};
fn(obj);
console.log(obj);//{a: 5, b: 2, c: 3}

ps:如果引用赋值后将对象置空,则相互不受影响

var obj = {a:1,b:2,c:3};
var obj3 = obj;
obj = {};
obj.a = 5;
console.log(obj3);//{a: 1, b: 2, c: 3}
console.log(obj); //{a: 5}

4、如何实现深拷贝:不同的写法及情况

第一级深拷贝,以后级别浅拷贝

1)解构赋值

var obj = {a:{i:1,j:2,k:3},b:2,c:3};
var obj1 = {...obj}
obj1.b=5;
console.log(obj);//{a:{i:1,j:2,k:3},b:2,c:3};
obj1.a.i=5;
console.log(obj);//{a:{i:5,j:2,k:3},b:2,c:3};

2)Object.assign()

var obj = {a:{i:1,j:2,k:3},b:2,c:3};
var obj2 = Object.assign({},obj);
obj2.b=5;
console.log(obj);//{a:{i:1,j:2,k:3},b:2,c:3};
obj2.a.i=5;
console.log(obj);//{a:{i:5,j:2,k:3},b:2,c:3};

深拷贝

1)递归

function deepCopy=()=>{

}

2)json

 

3)Object.create()

 

5、另:数组怎么写

slice contact 解构 Array.from 

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄