知识点

var 声明变量:
1、存在变量提升,实际上var无论在哪里声明,都会被当做当前的作用域顶部声明变量。
2、可以重复声明,后声明的变量会覆盖前声明的变量。
let 声明变量:
1、不存在变量提升。
2、禁止重复声明。
3、块级作用域,只在当前作用域块有用。
4、临时死区,而且不能在声明之前访问它。
const声明常量:
1、const 声明的是常量,其值一旦确定后不可以修改
2、const 声明常量时候必须要进行赋值
3、const 不存在变量提升,一旦执行快外就会立即销毁。
4、const 只能在当前代码块级有效,
5、const 不能重复声明相同常量。
6、const声明不允许修改绑定,但允许修改值,也就是说用const创建对象后,可以修改该对象的属性值。

一、声明JavaScript的变量有哪些?

每种编程语言都有变量,声明变量的方法各不同,在JavaScript里面,最经典的var声明一个变量,当ECMAScript6出现后,新增了2个声明变量的方法:let和const,那何时创建变量,用什么声明变量方法会更好呢?

二、先谈谈var声明及变量提示(hoisting)机制

var声明一个变量时候,只需要 var name; 或者声明赋值var name = "Bob";

实际上var无论在哪里声明,都会被当做当前的作用域顶部声明变量。

(1)什么是变量提示机制?
// var 的变量提升机制
function getValue(condition) {if (condition) {var values = 'Bob';return values;} else {console.log(values); // 这里访问到values 是undefined,原因下面解释:return null;}
}// 原因解释:为什么上面的代码else还能访问values的值,虽然是undefined
// 无论变量values都会被创建,在编译过程中,JavaScript引擎会将上面的getValue函数修改成这样:
function getValue(condition) {// 重点看这里,变量values的声明被提升到函数顶部var values;if (condition) {values = 'Bob';return values;} else {console.log(values); // 所以这里访问到是声明过的但未赋值的values,所以是undefined。return null;}
}

三、块级声明的出现

块级声明用于声明在指定的块的作用域之外无法访问的变量

  • 函数内部
  • 块级中(字符{ }之间的区域)

四、let声明

let声明变量和var声明变量,但let有自己的四个特征:

  • 块级作用域,限制在当前的块级作用域中,外面作用域无法访问。
  • 不存在变量提升。
  • 临时死区,而且不能在声明之前访问它。
  • 禁止重复声明相同的变量,否则报错。

我们可以把刚才聊到的getValue函数修改一下:

// let 块级作用域 && 不存在变量提升
function getValue(condition) {if (condition) {// 使用let声明变量let values = 'Bob';return values;} else {console.log(values); // 这里报错: ReferenceError: values is not defined..// 原因就是用let声明的变量,是不存在变量提升的,// 而且values变量只能在if{ 这个作用块里面有效 } 外面是访问不到的// 同时,在外面访问不仅会访问不到,而且会报错return null;}
}// let 禁止重复声明相同变量
function getValue() {var values = "Bob";let values = {name: 'Bob'};// 使用let声明变量禁止重复声明已经有的变量名// 否则报错:SyntaxError: Identifier 'values' has already been declared
}

五、const声明

  • const 声明的是常量,其值一旦确定后不可以修改。
  • const 声明常量时候必须要进行赋值。
  • const 不存在变量提升,一旦执行快外就会立即销毁。
  • const 只能在当前代码块级有效,
  • const 不能重复声明相同常量。
  • const声明不允许修改绑定,但允许修改值,也就是说用const创建对象后,可以修改该对象的属性值。
function getValue() {// 声明一个常量const USER_NAME = "梁凤波";// 禁止重复声明相同常量,否则报错:TypeError: Assignment to constant variable.// const USER_NAME = "Bob";// 记住:const声明不允许修改绑定,但允许修改值,// 也就是说用const创建对象后,可以修改该对象的属性值const STUDYENT = {name: '梁凤波'};console.log(`STUDYENT.name =  ${STUDYENT.name}`); // STUDYENT.name =  梁凤波STUDYENT.name = 'Bob';console.log(`STUDYENT.name =  ${STUDYENT.name}`); // STUDYENT.name =  Bob
}

拓展:循环中的块级作用域绑定

访问for循环后的结果
// 在for循环内用var 声明,在外面访问到的是for循环后的结果
for (var i = 0; i < 10; i++) {
}
console.log(`i = ${i}`); // i = 10// 在for循环内用let 声明,在外面 访问不到,块级作用域问题
for (let i = 0; i < 10; i++) {
}
console.log(`i = ${i}`); // ReferenceError: i is not defined
循环中的var声明
// 经过for循环后,在外面访问i,是直接访问到了结果i = 10let funcs = [];
for (var i = 0; i < 10; i++) {funcs.push(function () {console.log(i);})
}funcs.forEach(func => {func() // 分别输出10次10
});

原因:循环里每次迭代同时共享着变量i,循环内部创建的函数全保留相同变量的引用,循环结束时候i的值变为10,所以每次调用console.log(i)时候回输出数字10

为了解决这个问题,可以在循环中使用立即调用函数表达式(IIFE),以强制生成计数器变量的副本:

使用var达到理想状态
// 如果要理想效果,在外面分别输出 0 ~ 9,
// 可以使用闭包暴露出去
let funcs = [];
for (var i = 0; i < 10; i++) {funcs.push((function (val) {return function () {console.log(val);}}(i)))
}funcs.forEach(func => {func()
});
循环中的let声明
let funcs = [];
for (let i = 0; i < 10; i++) {funcs.push(function () {console.log(i);})
}funcs.forEach(func => {func() // 分别输出 0 ~ 9
});

let 声明模仿上述示例IIFE所做的一切简化循环过程,每次迭代循环都会创建一个新变量,并以之前迭代中同名变量的值将其初始化。

循环中的const声明
let funcs = [];
let obj = {a: true,b: true,c: true
}for (const key in obj) {funcs.push(function () {console.log(key);})
}funcs.forEach(func => {func() // 分别输出 a, b, c Authorization
});

let和const声明循环,const循环是不能改变key的值,const 循环应该使用for-in,for-of,其他和let示例一样,因为每次迭代不会像var循环例子一样修改已有的绑定,而是会创建一个新绑定。

全局块级作用域绑定

var RegExp = "Bob";// 即使是全局对象RegExp定义在window,也不能幸免被var声明覆盖
console.log(RegExp); // Bob
console.log(window.RegExp); // Boblet RegExp = "Bob";// 用let或const声明不能覆盖全局变量,而只能屏蔽它
console.log(RegExp); // Bob
console.log(window.RegExp); // undefined
console.log(window.RegExp === RegExp); // falseconst ncz = 'Hi!'
console.log('ncz' in window); // false

最后聊一聊块级绑定的最佳实践

默认使用const,只在确实需求改变变量的值使用let,这样就可以在某种程度上实现代码的不可变,从而防止默写错误产生。

深入理解ES6 - var-let-const相关推荐

  1. ES6之let(理解闭包)和const命令

    ES6之let(理解闭包)和const命令 最近做项目的过程中,使用到了ES6,因为之前很少接触,所以使用起来还不够熟悉.因此购买了阮一峰老师的ES6标准入门,在此感谢阮一峰老师的著作. 我们知道,E ...

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

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

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

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

  4. 深入理解ES6笔记(九)JS的类(class)

    主要知识点:类声明.类表达式.类的重要要点以及类继承 <深入理解ES6>笔记 目录 ES5 中的仿类结构 JS 在 ES5 及更早版本中都不存在类.与类最接近的是:创建一个构造器,然后将方 ...

  5. 理解es6中的暂时性死区

    引入 什么是作用域? 一段程序代码中所用到的名字并不总是有效/可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域. 全局作用域 JS中没有明确的全局作用域的概念,只有局部作用域以及全局执行环 ...

  6. ES6 let和const 命令

    ES6 let 和 const 命令 1. 变量声明 2. 变量提升问题 3. 暂时性死区(TDZ) 4. 块级作用域 4.1 为什么需要块级作用域? 4.2 ES6的块级作用域 4.3 块级作用域和 ...

  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. var,let,const 声明中一般人不知道的几个点

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

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

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

最新文章

  1. 在两个页面间翻转设置Animation动作的一些总结
  2. arcgis python工具-使用python制作ArcGIS插件(1)工具介绍
  3. vi 整行 多行 复制与粘贴
  4. 在一个空的Eclipse中安装Android开发的ADT和SDK
  5. 鸿蒙上海开发者日直播,华为鸿蒙 OS 开发者日于 4月17 日上海举行
  6. 【JSP】JSP与oracle数据库交互案例
  7. ajax和for循环谁难,关于“for”循环中jquery $ .ajax的问题
  8. error C2146: 语法错误 : 缺少“;”(在标识符“PVOID64”的前面)[转]
  9. eviews时间序列分析课堂笔记
  10. 淘宝API 添加上传商品图片
  11. turf.js API功能讲解
  12. 微信智能机器人助手,基于hook技术,自动聊天机器人
  13. SAP方丈 SAP常见问题与解决办法 转
  14. linkerd mysql_《Linkerd官方文档》在本地运行Linkerd
  15. 拓嘉启远:关于拼多多搜索溢价,你了解多少
  16. 华为软件测试笔试真题,抓紧收藏不然就看不到了
  17. 小米MIX FOLD折叠屏上手体验:MIUI大更新 满血的掌上PC模式“有点狠”
  18. 珠海化学分析实验室建设思路
  19. 2019 年(H 题)模拟电磁曲射炮
  20. 又是神经网络!还能用来盗取XX女演员信息

热门文章

  1. SAP MM 标准的采购订单预付款功能介绍
  2. 自然语言处理的蓬勃发展及其未来
  3. 索尼大法要专门开始搞AI了,成立Sony AI,发力游戏、影像和美食
  4. ETC带火车牌识别设备 多方企业狭路相逢
  5. 2019年上半年收集到的人工智能自动驾驶方向干货文章
  6. Python统计学-006:描述统计-方差
  7. SAP MM 预留单据里的Base date和Requirement date
  8. 干货丨浅析分布式系统(经典长文,值得收藏)
  9. 2021年14项世界互联网领先科技成果发布
  10. 11大改革举措!国家自然科学基金2021年项目指南发布