JS Statements var / let / const
关键字 | 范围 | 变量提升 | 可以重新分配 | 可以重新定义 |
---|---|---|---|---|
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相关推荐
- Js中var,let,const的区别
一:区别: 1.var声明的变量属于函数作用域,而let和const声明的变量属于块级作用域:(js作用域在上篇文章) 2.var声明的变量存在变量提升,而let和const没有 3.var声明的变量 ...
- 前端开发:JS中let、var和const的区别详解
前言 前端开发过程中,JS声明变量的关键字想必开发者都不陌生,而且使用的频率在前端开发过程中也是数一数二的.JS中声明变量的关键字有三个let.var和const,但是三者的使用对比和区别也是非常重要 ...
- js regex var highlight
js & regex & var & highlight let key = `ali`.toLocaleUpperCase(); let name = "阿里云计算 ...
- var,let,const 声明中一般人不知道的几个点
关于var,let,const 声明变量时,有几个特别注意的点,面试的时候极容易被问到,但是很多人特别容易说不清.let的作用域呀,暂时性死区,const作用域等. 文章目录 前言 一.小姐姐知道的l ...
- ES6基础(var let const 箭头函数)-学习笔记
文章目录 ES6基础(var let const 箭头函数)- 学习笔记 定义:var let const 箭头函数 数据结构 set map ES6基础(var let const 箭头函数)- 学 ...
- ES6学习(var,let,const区别)
本人写这个专题的博客是为了总结一下自己学习,使用还有刷题时学到的ES6知识点,并做以归纳. var,let,const 三个属性都可以声明变量. 作用域 var 重新赋值,重新定义变量,可以重复声明 ...
- var/let/const、块级作用域、TDZ、变量提升
概览 ES6 新增了两个定义变量的关键字:let 与 const,它们几乎取代了 ES5 定义变量的方式:var.let是新的var,const简单的常量声明. function f() {{let ...
- Var let const 的区别
Var let const 的区别 变量提升 var 存在变量提升 变量可以在声明之前调用 但是值为undefined. let ,const 不存在变量提升.他们声明的变量必须在声明后调用 如果在之 ...
- js中定义变量之②var let const的区别
var 上一篇文章有讲过,是js定义变量的关键词. 但是在es6中,新添加了两个关键词,用于变量声明的关键词:let 和const 接下来就说一下var let 和const的区别: 首先说var 用 ...
最新文章
- React.js 小书 Lesson12 - state vs props
- GTK+, Qt, wxWidgets compare
- svn 代码管理工具
- oracle重建服务器,Oracle重建控制文件的实例教程
- 【kafka】kafka 同时建立很多消费者 会怎么样
- 腾讯课堂:了解it技术圈的虚拟化容器化之docker
- python工资一般多少西安-西安Python的就业方向有哪些?
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第三节SpringBoot热部署devtool和配置文件自动注入实战_14、SpringBoot2.x使用Dev-tool热部署...
- 图像分割并存储 matlab,用于面积增长的Matlab图像分割程序
- 智能问答机器人python_帮帮智能问答机器人中TaskBot任务对话算法实践
- python语句分号_Python中的分号
- Clonezilla克隆还原系统
- AlibabaCloud
- 使用Hooks实现防抖节流 TS版本
- 2013年大学英语专升本作文——Should One Expect a Reward When Doing a Good Deed?【标准答案、精品范文答案】
- mbp使用brew安装unrar
- 如何测试硬盘软件,如何进行硬盘测试?磁盘健康检测方法介绍
- MATLAB柱状图画法(详细)
- 查询建立连接的IP地址
- AVL_全选_取消全选_打印_ZMM1035
热门文章
- 树莓派智能家居-语音聊天机器人实现
- niosii spi 外部_NIOS II SPI详解 如何使用SPI方式传输
- elementui带输入建议查询_elementUi简单实现搜索提词功能
- jupyternotebook 报告_基本操作!在VS 代码中如何使用Jupyter Notebook
- SpringBoot 中的事务处理 @Transactional
- linux如何查看所有的用户和组信息?
- 15个Linux Yum命令实例--安装/卸载/更新
- [转帖]win10 .Net Runtime Optimization Service占用大量CPU资源解决方法
- git新建分支并且在切换分支开发
- redis 介绍和常用命令