目录
一、基本类型和引用类型
1、基本类型
基本类型:undefined、null、Boolean、String、Number
基本类型的数据保存在栈内存
栈内存中分别存储着变量的标识符以及变量的值 栈内存中分别存储着变量的标识符以及变量的值
var name='曹操';
var gender='男';
栈内存 | |
---|---|
变量 | 值 |
name | ‘曹操’ |
gender | 男‘’ |
基本类型 的复制:当你在复制基本类型的时候,相当于把值也一并复制给了新的变量。
2、引用类型
引用类型: 统称为Object类型,细分的话,有:Object类型,Array类型,Date类型,Function类型等。
引用类型 保存在 堆内存 中, 栈内存存储的是变量的标识符以及对象在堆内存中的存储地址,当需要访问引用类型(如对象,数组等)的值时,首先从栈中获得该对象的地址指针,然后再从对应的堆内存中取得所需的数据。
var name1={name: '刘备'};
var name2={name: '关羽'};
栈内存 | 堆内存 | |
---|---|---|
变量 | 值 | 值 |
name1 | 堆地址1 | {name:' 刘备 '} |
name2 | 堆地址2 | {name: ‘ 关羽 ’} |
引用类型 的复制:当你在复制引用类型的时候,实际上只是复制了指向堆内存的地址,即原来的变量与复制的新变量指向了同一个东西。
二、深拷贝和浅拷贝
1.浅拷贝
只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,修改新对象会改到原对象。
(1)通过= 直接赋值
var obj1 = {
name: '诸葛亮',
gender: '男',
age: 20
};
var obj2 = obj1;
console.log(obj2); // name: '诸葛亮', gender: '男', age: 20
obj2.age = 30;
console.log(obj2); //name: '诸葛亮', gender: '男', age: 30
console.log(obj1); //name: '诸葛亮', gender: '男', age: 30
(2)Object.assign()方法
var obj1 = {
name: '诸葛亮',
gender: '男',
age: 20
};
var obj2=Object.assign(obj1)
obj2.age = 30;
console.log(obj2.age); // age: 30
console.log(obj1.age); // age: 30
2.深拷贝
会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
(1)通过JSON对象来实现深拷贝
JSON.stringify() 方法将一个 JavaScript 值(对象或者数组)转换为一个 JSON 字符串。
JSON.parse() 方法用来解析JSON字符串,构造由字符串描述的JavaScript值或对象。返回值为Object 类型, 对应给定 JSON 文本的对象/值。
该方法的原理是先将引用类型的对象转换为基础类型的字符串,然后将其从字符串再重新转换为对应的引用类型对象,在进行转换为引用对象的时候,会为对象的每个属性重新分配堆内存,即进行了深拷贝
var obj3 = {
number: 1111,
city: '西安'
}
var obj4 = JSON.parse(JSON.stringify(obj3));
obj4.city = '深圳';
console.log(obj3.city); //'西安'
console.log(obj4.city); //'深圳'
(2) Object.create()方法
var obj3 = {
number: 1111,
city: '杭州'
}
var obj4 = Object.create(obj3)
obj4.city = '深圳';
console.log(obj3.city); //'杭州'
console.log(obj4.city); //'深圳'
(3)使用扩展运算符实现深拷贝
// 当value是基本数据类型,比如String,Number,Boolean时,是可以使用拓展运算符进行深拷贝的
// 当value是引用类型的值,比如Object,Array,引用类型进行深拷贝也只是拷贝了引用地址,所以属于浅拷贝
var obj3 = {
number: 1111,
city: '杭州'
}
var obj4 = { ...obj3, number: 2021 }
console.log(obj3.number); //1111
console.log(obj4.number); //2021
要点:
深浅拷贝,都是进行复制,那么区别主要在于复制出来的新对象和原来的对象是否会互相影响,改一个,另一个也会变。
- 新旧对象共享内存,修改其中一个则会影响另外一个,则为浅拷贝;
- 新旧对象不共享内存,修改其中一个不会影响另一个,则为深拷贝。