当前位置: 首页 > news >正文

【ES6】—let 声明方式

一、不属于顶层对象window

  1. let 关键字声明的变量,不会挂载到window的属性
var a = 5
console.log(a)
console.log(window.a)
// 5
// 5
// 变量a 被挂载到window属性上了 , a = window.alet b = 6
console.log(b)
console.log(window.b)
// 6 
// undefined

小节:
var 声明的变量,会挂载到window的属性,容易造成全局变量污染

二、不允许重复声明

  1. let 关键字 不可以声明相同的变量,在运行阶段直接报错
var a = 5
var a = 6
console.log(a)
// 6 let b = 7
let b = 8
console.log(b)
// Uncaught SyntaxError: Identifier 'b' has already been declared
// b已经声明过了,不允许重复声明

小节:
var 可以声明相同变量,后声明的变量的值会覆盖前面声明的变量的值

三、不存在变量提升

  1. let 关键字不会把变量声明,放到代码的最前面,只会再执行时声明
console.log(a)
var a = 6
// 等同于
var a 
console.log(a)
a = 6
// undefinedconsole.log(b)
// 报错, 没有声明
let b = 7

小节:
使用 var 关键字声明的变量,无论代码在何处,都会把变量声明放到代码的最前面

四、暂时性死区

  1. 暂时性死区:先使用变量,再使用let关键字声明变量,就会出现暂时性死区,因为没有先声明就赋值了
var a = 5
if (true) {a = 6let a
}
// Uncaught ReferenceError: Cannot access 'a' before initialization

小节:
a 首先是全局变量,然后 给a 赋值,再使用let 关键字 声明变量 a, 这时候a 变成了局部变量,局部变量 a 先被使用了,再声明就会出现暂时性死区

  1. 隐蔽的暂时性死区
// 给参数设置默认值
function foo (a = b, b =2) {console.log(a, b)
}
foo()
// Uncaught ReferenceError: Cannot access 'b' before initialization
// b 再声明之前,你不能使用它
// a = b, b =2  因为代码从左往右执行, a = b, 表示把b的值赋给a, 但是b现在还没有声明和赋值,所以就出现了暂时性死区
  1. 改造后
// 给参数设置默认值
function foo (a = 2, b = a) {console.log(a, b)
}
foo()
// 2 2
// a = 2, b = a , 先声明了a 并赋值,再把a的值赋给b ,是没有问题的

小节:
局部变量先声明,再赋值,就不会出现暂时性死区

五、块级作用域

  1. var 声明的变量只有全局作用域和函数作用域,没有块级作用域, 所以 var 声明变量再任何地方都可以使用
for (var i =0; i< 3; i++) {console.log('循环内:' + i)
}
console.log('循环外', + i)
// 循环内:0
// 循环内:1
// 循环内:2
// 循环外 3
  1. 块级作用域: 指的是大括号{}里面,使用let关键字 声明的变量,只能在大括号里面使用,大括号外无法使用
    把 var 改成 let
for (let i =0; i< 3; i++) {console.log('循环内:' + i)
}
console.log('循环外', + i)
// 循环内:0
// 循环内:1
// 循环内:2
// Uncaught ReferenceError: i is not defined , i没有声明
  1. var 没有块级作用域,示例2
if (false) {var a = 5
}
console.log(a)
// undefined

小节:
因为 var 没有块级作用域,加上var 可以变量提升, 所以代码等同于

var a 
if (false) {a = 5
}
console.log(a)
// undefined

把 var 改造成let

if (false) {let a = 5
}
console.log(a)
// Uncaught ReferenceError: a is not defined
// a 因为大括号使用let关键声明,所以有块级作用域,大括号外无法使用
  1. ES6 中使用let 关键字声明的变量 所产生块级作用域,必须要有大括号,不能省略, 否则报错
if(true) let a =5
// Uncaught SyntaxError: Lexical declaration cannot appear in a single-statement context

优化后

if(true){let a =5
}
  1. 常见面试题
for (var i =0; i < 3 ; i++) {setTimeout(function (){console.log(i)})
}
// 打印3 个 3

因为遇到setTimeout是异步任务,会先放入事件处理器中,等待运行栈的同步任务执行完成之后,再把异步任务放入任务队列中,再从任务队列中一个个放入运行栈中执行
小节:每个定时器执行时,都是再for循环之后取值,所以打印3个3

  1. 通过闭包实现定时器按顺序打印
for (var i = 0; i < 3 ; i++) {// 立即执行函数, 一次性使用(function(j){ // j 表示形参setTimeout(function (){console.log(j)})})(i) // i 表示实参
}

闭包: 有一个外部函数和内部函数,内部函数会调用外部函数的变量,这样就可以保证外部函数的变量的状态值不被释放,因为内部函数一直再引用着外部函数的值

  1. 通过let 关键字实现定时器按顺序打印
for (let i = 0; i < 3 ; i++) {setTimeout(function (){console.log(i)})
}

通过 babel在线工具 实现 ES6 语法转 ES5语法

var _loop = function _loop(i) {setTimeout(function (){console.log(i)})
}
for (var i = 0; i < 3; i++) {_loop(i);
}

小节:当使用let关键字声明的变量时,被定时器调用,转换为ES5语法时,自动的转换为闭包的形式,保留i循环的每一个的状态值不被释放

http://www.lryc.cn/news/133519.html

相关文章:

  • 【数据分析入门】Jupyter Notebook
  • 反射知识总结
  • MongoDB 安装 linux
  • 什么是KNN( K近邻算法)
  • Linux查看命令总结
  • npm报错 Cannot find module ‘@vuepress\core\node_m
  • mybatis入门环境搭建及CRUD
  • 小程序变化历史记录
  • jstack(Stack Trace for Java)Java堆栈跟踪工具
  • linux面试题整理
  • Linux笔记
  • Dockerfile制作Web应用系统nginx镜像
  • lama-cleaner:基于SOTA AI 模型Stable Diffusion驱动的图像修复工具
  • LVS-DR模式以及其中ARP问题
  • 2023-08-15 Untiy进阶 C#知识补充5——C#6主要功能与语法
  • 最新两年工作经验总结
  • MATLAB——线性神经网络预测程序
  • 面试之快速学习STL-迭代适配器
  • 【Linux】【驱动】杂项设备驱动
  • 【HCIP】10.路由策略
  • 【腾讯云Cloud Studio实战训练营】使用Cloud Studio社区版快速构建React完成点餐H5页面还原
  • 测试开发工程必备技能之一:Mock的使用
  • Qbytearray:从十六进制字符串转字节一些注意事项
  • 【Docker】Docker的使用案例以及未来发展、Docker Hub 服务、环境安全的详细讲解
  • Redis有哪几种内存淘汰策略?
  • 操作系统练习:在Linux上创建进程,及查看进程状态
  • Java虚拟机(JVM):垃圾收集算法
  • 【爬虫】Requests库的使用
  • 了解生成对抗网络 (GAN)
  • opencv-人脸关键点定位