1.var的迷幻操作
普遍的观点:JavaScript中的基本数据类型是保存在栈空间,而引用数据类型则是保存在堆空间里, 是否正确?
浏览器环境下JavaScript变量类型的运行实践结果:
var a = 10;
console.log(a);
console.log(window.a);
console.log(window["a"]);
console.log(window);
重点来了!根据普遍的观点来看,a这个基本数据类型的变量,应该老老实实的保存在栈空间里。
但是我们却挂载到window全局对象上,其实我们一开始入门JavaScript,就知道var声明的变量编译的时候会进行变量提升挂载到全局,而let和const没有这个问题。那是不是var这个坑爹声明的原因呢?(一脸懵逼ing😭😭)
2.那let和const的变量存在哪里勒?
我们运行如下代码,打开控制调试,F5刷新debugger,并在Sources下查看数据的内存位置:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
<script>
var a = 10;
let b = 20;
const c = 30;
debugger;
console.log(a,b,c);
</script>
</html>
个人分析:
我们可以清楚的看到全局作用域下有两个对象,分别是Script对象和global(window)对象。Script对象存储了let和const定义的变量,global存储了var定义的变量。其实var,let和const并底层存储位置其实都是是对象,只不过不是同一个对象罢了。他们三者绑定对象的区别,是底层机制的不同,但是不是今天的重点,想起来有空再填坑 !
现在我们知道了不管是var还是let和const其实数据存储都是存储到对象内。那么这是不是JavaScript底层数据存储机制的问题呢?
3.有请我的大宝贝
经过我一段时间的调戏提问终于了解到JavaScript的底层存储机制:
在JavaScript中,任何数据其实都是以对象的形式存储的。所以说,JavaScript 中的基本类型和引用类型的数据底层都是存储在堆中的对象中。JavaScript中的所有对象都可以视为一种底层关联数组,究其原因,是因为每个对象都有一个内部属性 [[Prototype]](它指向原型对象)。这里又涉及到原型链的构成,不细说了,又是一个坑😂😂。
变量var,let和const声明的变量存储在变量对象中,变量对象是一个抽象概念,它并不存在于 JavaScript 的内存中。在代码执行过程中,JavaScript 引擎会自动创建变量对象,并将变量对象存储在执行上下文中。
尽管在JavaScript中没有像其他编程语言一样的显式堆栈结构,但JavaScript引擎在内部仍然使用类似的内存管理机制(自动垃圾回收->下次再说😜)来管理对象和变量。因此,我们可以将变量和对象的存储方式类比为栈和堆,这有助于我们理解JavaScript的内存管理机制(其实大家都没错,理解的层级不一样罢了)
所以网上的说法其实也没有错只是为了方便大家理解,当然想在面试中吊打面试官就得把底层撸的明明白白才行。不然怎么聊火箭的建成到发射。如有错误欢迎大家指正!