关键字 范围 变量提升 可以重新分配 可以重新定义
var 全局、局部 Yes Yes Yes
let 局部 No Yes No
const 局部 No No No

能用const的情况尽量使用const,其他情况下大多数使用let,避免使用var

var

  • 在ES5中,顶层对象的属性和全局变量是等价的,用var声明的变量既是全局变量,也是顶层变量

    • 注意:顶层对象,在浏览器环境指的是window对象,在 Node 指的是global对象
    var a = 10;
    console.log(window.a); // 10
    
  • 使用var声明的变量存在变量提升的情况

    console.log(a) // undefinedvar a = 20// 在编译阶段,编译器会将其变成以下执行var aconsole.log(a)a = 20
    
  • 使用var,能够对一个变量进行多次声明,后面声明的变量会覆盖前面的变量声明

    var a = 20;var a = 30;console.log(a); // 30
    
  • 在函数中使用使用var声明变量时候,该变量是局部的

    var a = 20;function change() {var a = 30;}change();console.log(a); // 20
    
  • 在函数内不使用var,该变量是全局的

    var a = 20;function change() {a = 30;}change();console.log(a); // 30
    

var a = 1 or a = 1; 的区别

  • 用var声明的全局变量,其[[Configurable]]属性为false。

    • 此时它就不能在声明后被delete,或者是被改为accessor property等。
    • 能做的操作只有访问或修改其[[Value]]属性的值,对例子中的a来说就是普通的读取a或对a赋值,而不能做其它操作。
  • 直接赋值来创建的全局变量,其[[Configurable]]属性为true,也就可以对它做任意修改,
    • 例如delete、改变其[[Enumerable]]属性的值,等等
var a = 1;b = 1;Object.getOwnPropertyDescriptor(this, 'a');// {value: 1, writable: true, enumerable: true, configurable: false}Object.getOwnPropertyDescriptor(this, 'b');// {value: 1, writable: true, enumerable: true, configurable: true}

MDN Object.getOwnPropertyDescriptor() 返回指定对象上一个自有属性对应的属性描述符

  • var a = 1;

    • 其一,声明前置,在编译时被提升到当前所在作用域的最顶部;
    • 其二,a = 1,在运行时进行的进行赋值;
  • Node.js 实现了 CommonJS 标准。
    • node 里会外包一层,所以 var a = 1 和 a = 1 不是一个域。
    • 代码一中 变量a在Local中,而代码二中变量a在Global中。
  • 严格模式下(即 ”use strict “)
    • a = 1; 会报错;

let

  • let是ES6新增的命令,用来声明变量

  • 用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效

    {let a = 20;
    }
    console.log(a); // ReferenceError: a is not defined.
    
  • 不存在变量提升

    console.log(a); // 报错ReferenceError
    let a = 2;
    
  • 这表示在声明它之前,变量a是不存在的,这时如果用到它,就会抛出一个错误

  • 只要块级作用域内存在let命令,这个区域就不再受外部影响

  • 使用let声明变量前,该变量都不可用(“暂时性死区”)

    var a = 123;
    if (true) {a = 'abc'; // ReferenceErrorlet a;
    }
    
  • let不允许在相同作用域中重复声明

    let a = 20;
    let a = 30;
    // Uncaught SyntaxError: Identifier 'a' has already been declared// 不通作用域没问题
    let a = 20;
    {let a = 30;
    }
    
  • 不能在函数内部重新声明参数

    function func(arg) {let arg;  // Uncaught SyntaxError: Identifier 'arg' has already been declared// var arg; // var 没问题
    }
    func();
    

const

  • const声明一个只读的常量,一旦声明,常量的值就不能改变;

  • const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动

  • 对于简单类型的数据,值就保存在变量指向的那个内存地址,因此等同于常量对于复杂类型的数据,变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的,并不能确保改变量的结构不变

    const a = 1;a = 3;// TypeError: Assignment to constant variable.
    
  • const一旦声明变量,就必须立即初始化,不能留到以后赋值

    const a;
    // SyntaxError: Missing initializer in const declaration
    
  • 之前用var或let声明过变量,再用const声明同样会报错

    var a = 20;
    let b = 20;
    const a = 30;
    const b = 30;
    // 都会报错
    
  • 复杂类型,不可改变数据指针,但是数据结构可变;

    const foo = {};// 为 foo 添加一个属性,可以成功
    foo.prop = 123;
    foo.prop; // 123// 将 foo 指向另一个对象,就会报错
    foo = {}; // TypeError: "foo" is read-only
    

区别

变量提升

  • var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined

  • let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则报错

      // varconsole.log(a); // undefinedvar a = 10;// letconsole.log(b); // Cannot access 'b' before initializationlet b = 10;// constconsole.log(c); // Cannot access 'c' before initializationconst c = 10;
    

暂时性死区

  • var不存在暂时性死区

  • let和const存在暂时性死区,只有等到声明变量的那一行代码出现,才可以获取和使用该变量

      // varconsole.log(a); // undefinedvar a = 10;// letconsole.log(b); // Cannot access 'b' before initializationlet b = 10;// constconsole.log(c); // Cannot access 'c' before initializationconst c = 10;
    

块级作用域

  • var不存在块级作用域

  • let和const存在块级作用域

      // var{var a = 20;}console.log(a); // 20// let{let b = 20;}console.log(b); // Uncaught ReferenceError: b is not defined// const{const c = 20;}console.log(c); // Uncaught ReferenceError: c is not defined
    

重复声明

  • var允许重复声明变量

  • let和const在同一作用域不允许重复声明变量

    // varvar a = 10;var a = 20; // 20// letlet b = 10;let b = 20; // Identifier 'b' has already been declared// constconst c = 10;const c = 20; // Identifier 'c' has already been declared
    

修改声明的变量

  • var和let可以

  • const声明一个只读的常量。一旦声明,常量的值就不能改变

    // varvar a = 10;a = 20;console.log(a); // 20//letlet b = 10;b = 20;console.log(b); // 20// constconst c = 10;c = 20;console.log(c); // Uncaught TypeError: Assignment to constant variable
    

Notion – The all-in-one workspace for your notes, tasks, wikis, and databases.https://serious-lose.notion.site/JS-Statements-560045bf4b534d1cbffbce3ef98a11bd

JS Statements var / let / const相关推荐

  1. Js中var,let,const的区别

    一:区别: 1.var声明的变量属于函数作用域,而let和const声明的变量属于块级作用域:(js作用域在上篇文章) 2.var声明的变量存在变量提升,而let和const没有 3.var声明的变量 ...

  2. 前端开发:JS中let、var和const的区别详解

    前言 前端开发过程中,JS声明变量的关键字想必开发者都不陌生,而且使用的频率在前端开发过程中也是数一数二的.JS中声明变量的关键字有三个let.var和const,但是三者的使用对比和区别也是非常重要 ...

  3. js regex var highlight

    js & regex & var & highlight let key = `ali`.toLocaleUpperCase(); let name = "阿里云计算 ...

  4. var,let,const 声明中一般人不知道的几个点

    关于var,let,const 声明变量时,有几个特别注意的点,面试的时候极容易被问到,但是很多人特别容易说不清.let的作用域呀,暂时性死区,const作用域等. 文章目录 前言 一.小姐姐知道的l ...

  5. ES6基础(var let const 箭头函数)-学习笔记

    文章目录 ES6基础(var let const 箭头函数)- 学习笔记 定义:var let const 箭头函数 数据结构 set map ES6基础(var let const 箭头函数)- 学 ...

  6. ES6学习(var,let,const区别)

    本人写这个专题的博客是为了总结一下自己学习,使用还有刷题时学到的ES6知识点,并做以归纳. var,let,const 三个属性都可以声明变量. 作用域 var  重新赋值,重新定义变量,可以重复声明 ...

  7. var/let/const、块级作用域、TDZ、变量提升

    概览 ES6 新增了两个定义变量的关键字:let 与 const,它们几乎取代了 ES5 定义变量的方式:var.let是新的var,const简单的常量声明. function f() {{let ...

  8. Var let const 的区别

    Var let const 的区别 变量提升 var 存在变量提升 变量可以在声明之前调用 但是值为undefined. let ,const 不存在变量提升.他们声明的变量必须在声明后调用 如果在之 ...

  9. js中定义变量之②var let const的区别

    var 上一篇文章有讲过,是js定义变量的关键词. 但是在es6中,新添加了两个关键词,用于变量声明的关键词:let 和const 接下来就说一下var let 和const的区别: 首先说var 用 ...

最新文章

  1. React.js 小书 Lesson12 - state vs props
  2. GTK+, Qt, wxWidgets compare
  3. svn 代码管理工具
  4. oracle重建服务器,Oracle重建控制文件的实例教程
  5. 【kafka】kafka 同时建立很多消费者 会怎么样
  6. 腾讯课堂:了解it技术圈的虚拟化容器化之docker
  7. python工资一般多少西安-西安Python的就业方向有哪些?
  8. 小D课堂 - 零基础入门SpringBoot2.X到实战_第三节SpringBoot热部署devtool和配置文件自动注入实战_14、SpringBoot2.x使用Dev-tool热部署...
  9. 图像分割并存储 matlab,用于面积增长的Matlab图像分割程序
  10. 智能问答机器人python_帮帮智能问答机器人中TaskBot任务对话算法实践
  11. python语句分号_Python中的分号
  12. Clonezilla克隆还原系统
  13. AlibabaCloud
  14. 使用Hooks实现防抖节流 TS版本
  15. 2013年大学英语专升本作文——Should One Expect a Reward When Doing a Good Deed?【标准答案、精品范文答案】
  16. mbp使用brew安装unrar
  17. 如何测试硬盘软件,如何进行硬盘测试?磁盘健康检测方法介绍
  18. MATLAB柱状图画法(详细)
  19. 查询建立连接的IP地址
  20. AVL_全选_取消全选_打印_ZMM1035

热门文章

  1. 树莓派智能家居-语音聊天机器人实现
  2. niosii spi 外部_NIOS II SPI详解 如何使用SPI方式传输
  3. elementui带输入建议查询_elementUi简单实现搜索提词功能
  4. jupyternotebook 报告_基本操作!在VS 代码中如何使用Jupyter Notebook
  5. SpringBoot 中的事务处理 @Transactional
  6. linux如何查看所有的用户和组信息?
  7. 15个Linux Yum命令实例--安装/卸载/更新
  8. [转帖]win10 .Net Runtime Optimization Service占用大量CPU资源解决方法
  9. git新建分支并且在切换分支开发
  10. redis 介绍和常用命令