let&const VS var&function 区别

766 阅读3分钟

一、let&const VS var&function 区别

1668304563081(1).png

1.词法分析

  • var/function语法上允许相同上下文中“重复去声明一个变量”,只不过浏览器渲染的时候,不会去重复声明;
  • 但let/const/class,从语法上就不支持重复声明「报SyntaxError」,而且所谓的不允许重复声明,是不论当前上下文中,我们基于何种方式,只要声明过这个变量,那么绝对不允许再拿let/const/class声明了;
    • 检测是否重复声明的事情,不是发生在代码执行阶段,而是在“词法分析阶段”,
    • 如果有重复声明的语法错误,则AST都不会生成{词法解析不通过},JS中所有代码也都不会在执行了!!
  • 我们从服务器端获取的到JS代码,本质是一堆字符串,而浏览器会把这堆字符串,按照ECMA262规范,解析为自己可以识别的JS代码...我们把这个过程,称之为“词法分析/解析”
  • 词法分析阶段,会把这堆代码变为浏览器可以识别的“树形结构 -> AST语法树”
// Uncaught SyntaxError: Identifier 'a' has already been declared //语法错误
//因为在代码执行前 要进行语法分析 然后检测到 a=>形参变量 let a 创建变量 所以报错
console.log('OK');
function sum(a) {
     console.log(a);
    let a = 100;
    console.log(a);
}
sum(200);

2.变量提升

var:存在变量提升

console.log(n);//undefined
var n=20;
console.log(n);

let&const 不存在变量提升

  • 所以变量只能在声明定义后使用,代码执行阶段遇到变量 在后面声明 会报无法在前面使用错误
console.log(a);//ReferenceError: Cannot access 'a' before initialization
let a=20;

3.和GO的关系「前提:全局上下文」

var/function

  • 在全局上下文中基于var/function声明的变量直接放到GO中;(如果是获取未声明的变量:报错;如果是直接赋值未声明的变量,相当于给window(GO)加属性)

const/let

  • 在全局上下文中基于const/let声明的变量放到全局VO(G)中

4.重复声明

var/function

  • 在语法上允许重复声明,但浏览器在实际运行中不会重新声明,而是重新赋值

let/const

  • 在词法分析阶段,在语法上就不允许重复声明,下面代码都不会执行

5.块级作用域

var

  • var与块级上下文没有关系,不受{}束缚,只出现var不会生成块级作用域

let/const/function

  • 除函数、对象的{}【例如循环体、判断体...】如{}内出现let/const/function,都会产生块级上下文,也会受块级上下文束缚【function有特殊性】

6.暂时性死区

console.log(a); //报错
console.log(typeof a); //"undefined" 基于typeof检测一个未被声明的变量,不会报错,结果是“undefined” => 可以理解为这是浏览器的一个BUG「暂时性死区」

//==================
console.log(typeof a); // Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 10;

二、let VS const

  • 变量:我们声明出来的名字「存储在VO/AO中的」
  • 常量:具体值
  • let/const声明的都是“变量”
    • const声明的变量有一个特点:“不能修改它的关联指向,一但和某个值关联,则不能再和其他值关联了”
    • const关联指向的值不能修改,但是如果是引用数据类型,可以修改地址内的内容
let a = 12;
a = 13; //让变量a重新和13关联
console.log(a); //13 

//===========================
const b = 12;
b = 13; //Uncaught TypeError: Assignment to constant variable.  const声明的变量有一个特点:“不能修改它的关联指向,一但和某个值关联,则不能再和其他值关联了”
console.log(b); */

//================================
const b; //Uncaught SyntaxError: Missing initializer in const declaration  并且const声明的变量,必须设置初始值

//=============================
//const关联指向的值不能修改,但是如果是引用数据类型,可以修改地址内的内容
const b = {
    name: '东方淼淼'
};
b.name = '钱多多';
console.log(b);