js编程-变量提升

102 阅读3分钟

变量提升:在当前上下文(全局/私有/块级)中,js代码自上而下执行之前,浏览器会提前处理一些事情(可以理解为词法解析的一个环节,词法解析一定发生在代码执行之前)。

  • 1、有var/function会变量提升(let/const不会) 不能在let/const之前使用变量
  • 2、浏览器老版本机制: 基于"var"或者"function"在全局上下中声明的变量(全局变量)会映射到GO(全局对象 window)一份,作为他的属性;一个修改,另外一个也会改。 浏览器新版本机制:在全局上下文中基于“VAR”或“funtion”声明的变量,只存储到GO(全局对象);新版本浏览器:除函数/对象等大括号外,在其他的大括号中出现(let/const/function),则会单独形成层块级私有上下文。

function a() {};

a = 1;

}

console.log(a); //老版本浏览器: 1 新版本浏览器:function foo() {}
解析:
    括号中带function的在新版中浏览器只会提前声明,不会赋值
    括号中functon 会形成块级私有上下文
    块级上下中遇到function foo() {} , 会对foo之前的操作映射到全局一份
  • 3、全局上下文中的变量提升,不论条件是否成立,都要进行变量提升(条件中带function的在新版中浏览器只会提前声明,不会赋值)会把当前上下文中所有带var/function关键字的进行提前声明和定义
  • var a = 10;

declare 声明 var a;

defined 定义 a = 10;

带var会提前声明, 带function 提前声明和定义

  • 匿名函数具名化

var func = function aaa() { console.log("aaaa") };

把原本作为值的函数表达式匿名函数“具名化“(这个名字不能在外面访问)不会在当前上下文中创建这个变量

当函数执行,在形成的私有上下文中,会把这个具名化的变量作为私有上下文中变量(值就是这个函数)来处理。

let VS const (全局上下文中,基于let/const声明的变量,只是在VO(G)中存储,跟GO无关;)

let 声明的变量,可以存储值也可以修改

const 声明的变量, 一旦赋值,就不可以与另外的值建立关系.(指针指向不可以改变)

let VS var
  1. var 存在变量提升, let 不存在变量提升;

  2. 全局上下文中,基于var声明的变量,相当于给全局对象GO添加了一个属性,但是基于let声明的变量,是全局变量,和GO没关系.

3)在相同的上下中,let不允许重复声明(不论之前基于何种方式声明,只要声明过,则都不能基于let声明); var可以, 浏览器只按照一次声明;

  1. let/const 暂时性死区

  2. let/const/function 会产生块级私有上下文,var没有