JavaScript对象的底层数据结构是什么

本文详细介绍了JavaScript中的数据类型,包括基本类型和引用类型,以及它们在栈和堆内存中的存储方式。讨论了基本类型和引用类型在值比较和可变性上的差异,并通过实例解析了浅拷贝和深拷贝的区别。此外,还提及了`typeof null`返回`object`的有趣现象。
摘要由CSDN通过智能技术生成

上一篇文章归纳了javascript的数据类型,归根到底数据类型就分为两类,一种是基础类型,一种是引用类型。如果还没有看的同学这里附上超链接《JavaScript规定了几种语言类型

基本类型
  • 内容:StringNumberBooleanUndefinedNullSymbolBigInt
  • 特点:值不可变,无属性无方法,保存在栈内存中、值比较。
String是一个特殊的基本类型,可以被当成引用类型使用
let a = 'strObject';
a = a.substring(3,9);
console.log(a); // Object
引用类型
  • 内容:除了上面的 7 种基本数据类型外,剩下的就是引用类型,统称为Object类型
  • 特点:引用类型的值同时保存在栈内存和堆内存中的对象。栈区内存保存变量标识符,堆内存存储对象的地址

ps:差异:基本类型的值是不可变的,比较是值的比较,引用类型的值是可变的,比较是引用的比较;

const a = '我是a';
let b = a;
console.log(a===b); // true
b = '我现在改了';
console.log(a); // 我是a
console.log(b); // 我现在改了
console.log(a===b); // false
/** =================== **/
const c = {
	name: '张三'
}
const d = c;
const e = {name: '李四'}
d.name = '李四';
console.log(c); // {name: "李四"},引用类型的赋值其实是对象保存在栈区地址指针的赋值,因此两个变量指向同一个对象,任何的操作都会相互影响。
console.log(d); // {name: "李四"}
console.log(e); // {name: "李四"}
console.log(c===d); // true
console.log(d===e); // false,虽然看起来相同,但是两个对象存在堆内存的地址是不相同的,所以返回的是false;

现在我们来了解下什么是堆,什么又是栈。

堆(heap)
  • 堆内存的简称,动态分配内存,内存大小不一,不是自动释放。
  • 队列优先,先进先出,方便存储和开辟内存空间。
栈(stack)
  • 栈内存的简称,自动分配相对固定大小的内存空间,并由系统自动释放。基本类型存储在栈内存的好处就是,内存可以及时的得到回收。
  • 线性结构,后进先出,便于管理。

ps:看完堆和栈的简单介绍,我们再来看下对于数据结构相关的一个问题浅拷贝和深拷贝

浅拷贝

只复制了第一层属性,复制对象是基本类型。

// 浅拷贝的方法
const a = {
	name: '张三'
}
// Object.assign或=
const b = Object.assign(a);// {name: '张三'}
b.name = '李四';
console.log(a.name); // 李四
const c = b;
c.name = '王五'
console.log(a.name); // 王五
console.log(b.name); // 王五
深拷贝

对属性中所有引用类型的值,遍历到是基本类型的值为止,利用递归来实现深拷贝。

// Object.assign和扩展符针对对象值都是基本类型
const a = {
	name: '张三';
}
const b = Object.assign({}, a); // 或者{...a}
b.name = '李四';
console.log(a.name);// 张三
// 递归循环
function clone(obj){
    let _obj = Array.isArray(obj) ? [] : {};
    if(obj && typeof obj === "object"){
        for(key in obj){
            if(obj.hasOwnProperty(key)){
                // 判断obj子元素是否为对象,如果是,递归复制
                if(obj[key] && typeof obj[key] === "object"){
                    _obj[key] = clone(obj[key]);
                } else {
                    // 如果不是,简单复制
                    _obj[key] = obj[key];
                }
            }
        }
    }
    return _obj;
};
const c = clone(a);
c.name = '王五';
console.log(a.name); // 张三

结尾附上一个有趣的问题typeof(null),打印出来的是object,原因JavaScript中的数据在底层是以二进制存储,比如null所有存储值都是0,但是底层的判断机制,只要前三位为0,就会判定为object

ps:文末附上汇总文章链接《一名【合格】前端工程师的自检清单【持续更新】

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

四点水的点滴记录

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值