
我最近在接受小组老板的采访时遇到了这样的问题,
问: 谈谈var,let和const之间的区别
A: 巴拉巴拉巴拉卜...
问: const定义的值可以更改吗?
A: 你在逗我吗?不能

我不知道法官的想法吗?答案是有些可以更改,而有些不能更改. const定义的基本类型不能更改,但是可以通过修改对象属性和其他方法来更改定义的对象. 例如,
>>> const a = 1
>>> a
<<< 1
>>> a = 2
<<< VM1750:1 Uncaught TypeError: Assignment to constant variable.
at :1:3
(anonymous) @ VM1750:1
>>> const b = {}
>>> b
<<< {}
>>> b.name = 1
>>> b
<<< {name: 1}
>>> b = {}
<<< VM1785:1 Uncaught TypeError: Assignment to constant variable.
at :1:4
不是常量定义吗?为什么要更改?这就是我们今天要谈论的重点〜
js中的堆内存和堆栈内存
在js引擎中存储变量的主要位置有两个,堆内存和堆栈内存.

类似于Java中的内存处理,堆栈内存主要用于存储各种基本类型的变量,包括布尔,数字,字符串,未定义,空,**和指向对象变量的指针. 这时,堆栈存储器给人的感觉就像是一个线性排列的空间,每个小单元基本上是相同的大小.
堆存储器主要负责存储诸如Object之类的变量类型,如下所示

堆栈存储器中的变量通常具有已知大小或范围的上限,并被视为简单存储. 存储在堆内存中的对象类型数据的大小通常是未知的. 就个人而言,这就是为什么将null作为对象类型变量存储在堆栈存储器中的原因.
因此,当我们定义一个const对象时,我们所讨论的常量实际上是一个指针,即指向const对象对应的堆内存的指针没有改变,但是数据本身的大小或属性在堆内存是可变的. 对于const定义的基本变量,该值等效于指向const对象的指针,并且是不可变的.

现在您知道const在内存中的存储,因此更容易猜测const和let不能定义两次的变量的过程. 每次使用const或let初始化变量时,都会先遍历该变量. 检查当前的内存堆栈,以查看是否有同名的变量,如果存在则返回错误.
谈到这一点,有一点很容易忽略. 我以前没有注意过. 使用new关键字初始化后,它不会存储在堆栈存储器中. 为什么?每个人都知道新实例是基于构造函数生成的. 此时,将生成对象而不是基本类型. 让我们来看另一个例子
var a = new String('123')
var b = String('123')
var c = '123'
console.log(a==b, a===b, b==c, b===c, a==c, a===c)
>>> true false true true true false
console.log(typeof a)
>>> 'object'
我们可以看到new是一个字符串,结果是一个对象,直接文字分配和工厂模式产生的都是字符串. 但是根据我们上面的分析,大小是相对固定的,可以预期甚至对象也可以存储在堆栈存储器中,例如null. 为什么不呢?继续观看
var a = new String('123')
var b = new String('123')
console.log(a==b, a===b)
>>> false false

很显然,如果a和b存储在堆栈内存中,则两者显然应该相等,就像null === null为true一样,但是结果不相等,表明两者都存储在堆内存中,指针点不一致.
在谈到这一点时,请再考虑一下我们经常谈论的值类型和引用类型. 实际上,我们指的是堆栈内存变量和堆内存变量. 考虑一下价值转移和参考转移,深层复制和浅层复制. 在堆栈内存中展开,一个是处理值,另一个是处理指针.
内存分配和垃圾回收
通常来说,堆栈存储器以线性顺序存储,容量小且系统分配效率高. 堆内存必须首先在堆内存中分配一个新的存储区域,然后将指针存储在堆栈内存中,这效率相对较低.
就垃圾回收而言,堆栈存储器变量在用完后基本上会被回收,并且由于对推入存储器中的变量有很多不确定的引用,因此只有在所有被调用的变量销毁之后才可以回收它们.
如果您继续考虑,仍然有很多事情需要学习. 今天到这里,我待会再补充.
顺便说一句〜NaN也将存储在堆内存中吗?大家考虑一下,欢迎一起讨论和讨论〜如果文本有任何错误,请指出〜
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/shoujiruanjian/article-303804-1.html
这样才能输了面子赢了里子
只有一计能救中国
好想去