1、let、const、var、function的区别

发布于 2022年 01月 20日 22:23

1、(let和const区别) let声明的是变量

const声明的是常量 (这种说法是错误的)

const声明的变量不能修改此变量的关联指向

+例子
    (1)let定义一个变量
         let n = 10;
         n = 12;
         console.log(n);    //12
    (2)const定义一个变量(声明常量(具体值) 错误的说法)
        const也是声明变量的,只不过不能修改此变量的关联指向
        const m = 10;
        m = 12; //Uncaught TypeError: Assignment to constant variable.
        console.log(m);
    (3)const声明一个对象,但是这个对象的内容可以改变,只是指向不能改变(所以说声明的是一个常量是错误的)
        const m = {
        name: 'zhufeng'
        };
        m.name = 'peixun';
        console.log(m); //->{name:'peixun'} 

2、重复声明:

相同上下文中,var允许重复声明「只识别一次」;let不允许重复声明(不论基于啥声明过,再基于let/const声明都会报错);

  var n = 10;
  var n = 20;
  console.log(n); //->20 */

  /* // Uncaught SyntaxError: Identifier 'n' has already been declared  在词法解析阶段,如果报错,则所有代码都不执行
  console.log('OK');
  let n = 10;
  let n = 20;
  console.log(n); 

3、var、function存在变量提升(var 、let、function区别)

变量提升:把当前上下文中所有带var/function关键字的进行提前的声明或者定义(var->声明 function->声明+定义)

let 不允许在它未声明之前使用

  // console.log(n); //->undefined
  // var n = 10;

  // console.log(n); //->Uncaught ReferenceError: Cannot access 'n' before initialization
  // let n = 10;

4、基于var/function声明的变量:除了往全局变量对象中存储一份,而且也给GO(window)设置了对应的属性 「映射机制」(新版处理机制:在全局上下文中,基于var/function声明的变量,直接存储到GO中(VO(G)中不留了))

  // var n = 10;
  // console.log(n); //->10
  // console.log(window.n); //->10
  // window.n = 20;
  // console.log(n); //->20
  
  // n = 10; //->GO:{n:10} 设置:直接给GO设置
  // console.log(n); //->先看VO(G)中有没有,如果有就是全局变量的操作,如果没有,再看GO中有没有...如果还没有,则报错:变量未定义

  // 基于let/const声明的变量,只会存储到VO(G)中,和GO没有任何的关系
  // let n = 10; //->VO(G)  n->10
  // console.log(n); //=>10
  // console.log(window.n); //=>undefined

5、暂时性死区

// JS中的暂时性死区:基于typeof检测一个未被声明的变量,不会报错,结果是'undefined'
// console.log(typeof n); //->'undefined'

// console.log(typeof n); //Uncaught ReferenceError: Cannot access 'n' before initialization let的机制抵消了暂时性死区的机制
// let n = 10;

6、块级作用域

let会产生块级作用域(私有的上下文)

目前上下文类型:全局上下文、函数执行的私有上下文、块级私有上下文

除函数体以及创建对象的大括号外,其余大部分包含代码块的大括号(例如:判断体、循环体...)都有可能会产生块级上下文

   {
    /*
     * 在代码块中,首先看是否出现 let/const/function「特殊」,如果出现,此时就会形成一个块级私有上下文 
     *   EC(BLOCK)
     *     VO(BLOCK): m->20
     *     作用域链:<EC(BLOCK),EC(G)> 上级上下文就是代码执行所处的环境
     *     ->没有自己的THIS,用到的this用的也都是上级上下文中的
     *     ->没有arguments
     *     ->没有形参赋值
     *     ->有变量提升,也只是针对特殊的function
     * 即使产生块级上下文,对var的操作也是无效的「var不受块级上下文的影响」
     */
    var n = 10; //全局的n
    let m = 20; //块级私有的
    console.log(n, m); //->10/20
}
console.log(n); //->10
console.log(m); //->Uncaught ReferenceError: m is not defined

*一个小提示 let声明的变量类似有变量提升的概念

推荐文章