示例
值类型
let a = 100;
let b = a;
a = 200;
console.log(b); // 100 (互不影响)
引用类型
let a = { age: 20 };
let b = a;
a.age= 21;
console.log(b.age); // 21 (b.age随a.age的改变而改变)
存储方式
值类型
js变量存储在栈中,至于怎么存储咱先不管(毕竟我也不懂),这是js引擎的事情。
如图所示,key为变量名,value为存储内容,值类型变量的值直接存储在value中,a的值改变后并不会影响b的值。
引用类型
在栈中,引用类型存储的是内存地址,同时内存地址指向堆中的值,
简单地讲:引用类型a -> 内存地址1 -> a的值,此时若执行let b = a;
,则是把b的内存地址指向了a的内存地址,而这个内存地址指向同一个值,所以a的值改变的时候,b的值也随之改变。
为什么引用类型要搞个内存地址?
众所周知最常见的引用类型是对象和数组,数组长度和对象属性数量是没有限制的,甚至可以嵌套,如果像存储值类型那样存储引用类型(没有内存地址,直接存储在栈中),那计算机怕是要炸了。
常见值类型和引用类型
// 常见值类型
let a; // undefined
const n = 100; // Number
const s = '100'; // String
const b = true; // Boolean
const s = Symbol('s') // Symbol(es6)
// 常见引用类型
const obj = { value: 100 }; // Object
const arr = [ 1, 2, 3 ]; // Array
const n = null; // 特殊引用类型,指针指向空地址
function fn() {} // 特殊引用类型,但不用于存储数据,所以不考虑深拷贝浅拷贝的问题
深拷贝
- JSON.parse(JSON.stringify(obj))
最简单的方式,但会忽略undefined,function,RegExp - Object.assign()或解构赋值(
const a = {...obj}
,const b = [...arr]
)
只适合只有一层没有嵌套的对象或数组 - 递归
const deepCopy = obj => {
let copy = Array.isArray(obj) === true ? [] : {}
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof obj[key] === 'object') {
copy[key] = deepCopy(obj[key])
} else {
copy[key] = obj[key]
}
}
}
return copy
}
原文地址:https://www.cnblogs.com/deepdarkdeveloper/p/11888448.html
时间: 2024-10-10 09:11:04