# 变量、作用域和内存

# 变量

# 分类

包含两种不同的数据类型

  • 原始值(6种原始类型:Undefined/Null/String/Number/Number/Symbol)
  • 引用值(多个值构成的对象,保存在内存中的对象)

js不允许直接访问内存位置,不能直接操作对象所在的内存空间。操作对象时,实际上是操作的对象的引用,而非对象本身。

# 复制

原始值 原始值会被复制到新变量的位置,两个变量独立使用,互不干扰

引用值 复制的值实际上是一个指针,指向存储在堆内存中的对象,两个变量实际上指向同一个对象

函数参数传递 所有函数的参数都是按值传递的 函数外的值会被复制到函数内部的参数中

# 执行上下文

每个上下文都有一个关联的变量对象,上下文定义的所有变量和函数都在这个对象上

全局上下文是最外层的上下文 每个函数调用都有自己的上下文,当代码执行流进入函数时,函数的上下文被推到一个上下文栈。函数执行完之后,上下文栈会弹出该函数上下文,将控制权返还给之前的执行上下文。

# 作用域

上下文代码在执行的时候,会创建变量对象的一个作用域链。决定了各级上下文中的代码在访问变量和函数时的顺序。 代码正在执行的上下文的变量始终位于作用域的最前端,全局上下文的变量对象始终是作用域链的最后一个变量对象。

代码执行的标识符解析是通过沿作用域链逐级搜索标识符名称完成的,从作用域最前端开始,逐级往后,直到找到标识符。

# 变量提升

var声明会被拿到函数或者全局作用域的顶部,位于作用域所有代码之前。这个现象叫做提升。提升让同一作用域中的代码不必考虑变量是否已经声明就可以使用。

# let块级作用域声明

块级作用域:由最近的一对包含花括号{}界定

# var vs let

  • let作用域是块级的
  • let在同一作用域内不能声明两次,重复var声明会被忽略