JS基本数据类型和引⽤数据类型的区别及浅拷贝和深拷贝
JS基本数据类型和引⽤数据类型
再讲 js 的基本数据类型和引⽤数据类型之前,我们先说⼀下栈和堆的概念
1、栈(stack)和堆(heap)
栈(stack):
栈会⾃动分配内存空间,会⾃动释放,存放基本类型,简单的数据段,占据固定⼤⼩的空间。
堆(heap):
动态分配的内存,⼤⼩不定也不会⾃动释放,存放引⽤类型,指那些可能由多个值构成的对象,保存在堆内存中,包含引⽤类型的变量,实际上保存的不是变量本⾝,⽽是指向该对象的指针。
2、基本数据类型和引⽤数据类型
1. 基本数据类型:Number、String、Boolean、Null、 Undefined、Symbol(ES6),这些类型可以直接操作保存在变量中的实际值
1.1 基本数据类型特点:
1. 占⽤空间固定,保存在栈中
(当⼀个⽅法执⾏时,每个⽅法都会建⽴⾃⼰的内存栈,在这个⽅法内定义的变量将会逐个放⼊这块栈内存⾥,随着⽅法的执⾏结束,
这个⽅法的内存栈也将⾃然销毁了。因此,所有在⽅法中定义的变量都是放在栈内存中的;栈中存储的是基础变量以及⼀些对象的引⽤变量,
基础变量的值是存储在栈中,⽽引⽤变量存储在栈中的是指向堆中的数组或者对象的地址,这就是为何修改引⽤类型总会影响到其他指向这个地址
的引⽤变量)
2. 保存与复制的是值本⾝
3. 使⽤typeof检测数据的类型
4. 基本类型数据是值类型
2. 引⽤数据类型:Object(在JS中除了基本数据类型以外的都是对象,数据是对象,函数是对象,正则表达式是对象)
2.1 引⽤数据类型特点:
6. 占⽤空间不固定,保存在堆中
(当我们在程序中创建⼀个对象时,这个对象将被保存到运⾏时数据区中,以便反复利⽤(因为对象的创建成本通常较⼤)
,这个运⾏时数据区就是堆内存。堆内存中的对象不会随⽅法的结束⽽销毁,即使⽅法结束后,这个对象还可能被另⼀个引⽤变量所引⽤(⽅法的参数传递时很常见),
则这个对象依然不会被销毁,只有当⼀个对象没有任何引⽤变量引⽤它时,系统的垃圾回收机制才会在核实的时候回收它。)
7. 保存与复制的是指向对象的⼀个指针
8. 使⽤instanceof检测数据类型
9. 使⽤new()⽅法构造出的对象是引⽤型
3、基本数据类型(Number、String、Boolean、Null、Undefined、Symbol(ES6))存放在栈中
基本数据类型是指存放在栈中的简单数据段,数据⼤⼩确定,内存空间⼤⼩可以分配,它们是直接按值存放的,所以可以直接按值访问
var a =1;
var b = a;
b =2;
console.log(a);// 1
console.log(b);// 2
栈内存
4、引⽤数据类型(Object)存放在堆中
引⽤类型是存放在堆内存中的对象,变量其实是保存的在栈内存中的⼀个指针(保存的是堆内存中的引⽤地址),这个指针指向堆内存引⽤类型数据在栈内存中保存的实际上是对象在堆内存中的引⽤地址。通过这个引⽤地址可以快速查到保存中堆内存中的对象
var a ={
name:'lily',
age:'16'
}
var b = a;
b.name ='lokka';
console.log(a);// {name: "lokka", age: "16"}
把 a 赋值给 b ,就相当于把 a 的内存地址指向 b ,即 a 和 b 指向同⼀内存地址, 改变了 b 就相当于
改变了 a
浅拷贝和深拷贝
深拷贝和浅拷贝是只针对Object和Array这样的引⽤数据类型的。
1、概念
浅拷贝:只拷贝⼀层,深层次的对象级别只拷贝引⽤。
深拷贝:拷贝多层,每⼀级别的数据都会被拷贝出来。
2、浅拷贝的实现⽅式
1. ⽅法⼀:通⽤循环
function shallowCopy(obj){
if(typeof obj !=='object')return;
const newObj = obj instanceof Array ?[]:{};
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key]= obj[key];
}
}
return newObj;
}
2. ⽅法⼆:Object.assign
原生js和js的区别const newObj = Object.assign({}, oldObj);
注:对象只有⼀层是深拷贝
let obj ={
name:'lokka'
};
let obj2 = Object.assign({},obj);
obj2.name ='cola';
console.log(obj);//{username: "lokka"}
3. ⽅法三:Array.slice
const newArray = oldArray.slice();
4. ⽅法四:at
const newArray = at();
5. ⽅法五:es6
const newObj ={...oldObj };
const newArray =[...oldArray ];
3、深拷贝的实现⽅式
1. ⽅法⼀:通⽤循环
function deepCopy(obj){
if(typeof obj !=='object')return;
const newObj = obj instanceof Array ?[]:{};
for(let key in obj){
if(obj.hasOwnProperty(key)){
newObj[key]=typeof obj[key]==='object'?deepCopy(obj[key]): obj[key]; }
}
return newObj;
}
2. ⽅法⼆:JSON.parse、JSON.stringify
const newObj =JSON.parse(JSON.stringify(oldObj));

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。