1
作为前端开发者,我们每天都在初始化数不尽的变量。js中有基础数据和引用数据,那么他们是在js内存中是如何分配的呢?如果是初级开发者,可能对此有些模糊不清,那么接下来可以了解下关于变量内存分配,以及const、let和var的比较。
  1. 内存分配位置
    一般来说,我们可能认为在运行时,变量会被分配到调用栈里,然后在函数执行时调用不同的变量值来进行执行操作。其实在js中,基础类型数据是被分配到调用栈里,而引用类型数据是被分配到内存堆里的,它们是被分配到不同的地方。那么函数执行时怎么调用呢?让我们先看下面的一个问题
  2. 到底分配的是什么?值?还是其他
    2.1 当我们定义一个变量时,var name = 'feng',此时内存会进行以下操作。首先定义一个标识符,然后为变量值分配一个内存地址,在改地址存储变量值。那么我们一般都认为name等于feng字符串,这是一个误区。其实是为变量name分配了一个地址值,而该地址存储的是"feng":name->地址->'feng'。那这个地址不会变,如果我们此时name = 'not feng',是内存继续分配另一个地址来存储新的字符串,此刻name变量的值变化为新的地址,老的地址就与name无关了。
    2.2 如果我们定义一个引用类型数据变量呢var obj = {}?会首先定义一个标识符,然后在内存堆里分配一个地址来存储引用类型数据{},然后调用栈会分配一个地址来存储在内存堆的地址,在js运行时,obj->调用栈的地址->内存堆的地址->{}。
    address.jpeg
  3. 执行
    此时我们应该清晰了很多。当函数执行时,调用栈调用变量然后通过地址找到储存的变量值,然后再执行,就可以对变量进行任何合法的操作。
  4. const VS let
    es6引入了const和let的定义变量的方式,让我们在某种意义上可以直接避免一些变量定义带来的问题。那么他们有什么不同?
    4.1 我会倾向于,除了预测某个变量将来可变,其他的都用const。这样在代码层面,阅读者或者将来需要维护项目的朋友,可以更友好的确定,这就是他预想的代码逻辑,而不是看完一头雾水。毕竟js可是动(za)态(luan)语言。
    4.2 它们会带来一个var不曾有的特性,暂时性死区。这个问题清阅读es6-let和const:暂时性死区
    4.3 那么在其他语言中,常量意味着不可变性。但是const给人的是一种错觉,他无法保证定义的变量真的是不可变的。const arr = [],我们是可以对arr进行push、shift等任何对数组的合法操作。???const不是不可变吗?const a = 'abc',我改动a的值肯定出错了呀?它只能保证不会被分配到新的内存地址,而不是不可操作。如果执行arr = [1],就报错了。它只能保证基础类型数据,例如number,string等。所以如果需要,你可以使用Object.freeze(),来达到引用类型数据的不可变性。

fengxh
598 声望4 粉丝