es6 快速入门 系列 —— 变量声明:let和const
其他章节请看:
变量声明:let和const
试图解决的问题
经典的 var
声明让人迷惑
function demo1(v){
if(v){
var color='red'
}
console.log(color)
}
demo(1) // red
js引擎会将上面的 demo1 函数修改成下面的样子:
function demo2(v){
var color;
if(v){
color='red'
}
...
}
解决方法
将 var
声明改为 let
声明
function demo3(v){
if(v){
let color='red'
}
// 变量color在此处不存在
console.log(color)
}
demo3(1) // 报错
let
声明的用法与var
相同。用 let 代替 var 来声明变量,就可以把当前作用域限制在当前代码块(指块级作用域)中。由于 let 声明不会被提升,因此开发者通常将 let 声明语句放在代码块顶部,以便整个代码块都可以访问
最佳实践
起初,对很多js开发者来说,let
与他们实际想要的var
一样,所以直接将var
替换成let
。当更多的开发者迁移到es6后,另一种做法日益普及:默认使用const
,只有确实需要改变变量的值才使用let
,可能大部分的值在初始化后不会再改变。
补充
块级作用域
以前只有函数作用域,es6新增了块级作用域(字符{和}之间的区域)
// 函数作用域:变量i在函数demo4中有效
function demo4(){
if(true){
var i = 1
}
console.log(i)
}
demo4() // 1
console.log(i) // 报错(i没有定义)
// 块级作用域:变量i只在if中的{和}之间有效
function demo5(){
if(true){
let i = 1
}
console.log(i)
}
demo5() // 报错(i没有定义)
禁止重复声明
假设作用域中存在某变量(i),此时再用 let
或 const
关键字声明变量(i),就会抛出错误
var a = 1;
// 重复声明,抛出语法错误
let a = 1;
var a = 1;
if(1){
// 不会抛出错误(没有重复声明)
let a = 1;
}
const声明
es6提供 const
关键字来声明常量
常量必须一开始就初始化
// 正确
const i = 1
// 报错(常量未初始化)
const j;
不可以为 const 定义的常量再赋值(但允许修改值)
// 报错
const i = 1;
i = 2;
const obj = {}
// 正确(允许修改值)
obj.i = 1
// 错误(不允许修改绑定)
obj = {}
临时死区
用 let 或 const 声明的变量,会先存放在临时死区(TDZ)中,只有执行过变量声明语句后,变量才从TDZ中移除
if(true){
// 报错(访问临时死区中的变量,会报错)
console.log(typeof i)
let i = 1
}
循环中的块作用域绑定
var 声明让开发者创建函数非常困难
var funArr = []
for(var i = 0; i < 5; i++){
funArr.push(function(){
console.log(i)
})
}
funArr[0]() // 5
funArr[1]() // 5
我们的预期是输出0~4,这里却全部输出5
可以用立即调用函数表达式(IIFE)来达到目的,就像这样:
var funArr = []
for(var i = 0; i < 5; i++){
funArr.push(function(i){
return function(){
console.log(i)
}
}(i))
}
funArr[0]() // 0
funArr[1]() // 1
但我们可以用更简单的方式:循环中用 let 声明
var funArr = []
// 循环中用let声明:var 改用 let声明
for(let i = 0; i < 5; i++){
// let声明模仿上述例子中 IIFE 所做的一切(每次循环都创建一个新变量i,给新变量i赋值),
// 现在彻底删除 IIFE 之后仍可得到预期的结果
funArr.push(function(){
console.log(i)
})
}
funArr[0]() // 0
funArr[1]() // 1
注:let声明在循环内部的行为是标准中专门定义的,不一定与 let 的不提升特性相关
全局块作用域绑定
var 声明的变量,会覆盖已存在的全局属性;let 和 const 声明的变量不会覆盖全局属性
// 覆盖全局属性RegExp
var RegExp = 'hello'
console.log(window.RegExp) // hello
let RegExp = 'hello'
console.log(window.RegExp) // RegExp() { [native code] }
console.log(RegExp) // hello
其他章节请看:
es6 快速入门 系列 —— 变量声明:let和const的更多相关文章
- es6 快速入门 系列 —— 类 (class)
其他章节请看: es6 快速入门 系列 类 类(class)是 javascript 新特性的一个重要组成部分,这一特性提供了一种更简洁的语法和更好的功能,可以让你通过一个安全.一致的方式来自定义对象 ...
- es6快速入门 系列 - async
其他章节请看: es6 快速入门 系列 async 前文我们已经知道 promise 是一种异步编程的选择.而 async 是一种用于执行异步任务更简单的语法. Tip:建议学完 Promise 在看 ...
- es6 快速入门 系列 —— promise
其他章节请看: es6 快速入门 系列 Promise Promise 是一种异步编程的选择 初步认识Promise 用 Promise 来实现这样一个功能:发送一个 ajax,返回后输出 json ...
- es6 快速入门 系列 —— 对象
其他章节请看: es6 快速入门 系列 对象 试图解决的问题 写法繁杂 属性初始值需要重复写 function createPeople(name, age){ // name 和 age 都写了 2 ...
- es6 快速入门 系列
es6 快速入门(未完结,持续更新中...) 前言 为什么要学习es6 es6对于所有javaScript开发者来说,非常重要 未来,es6将构成javaScript应用程序的基础 es6中很多特性, ...
- es6 快速入门 —— 函数
其他章节请看: es6 快速入门 系列 函数 函数是所有编程语言的重要组成部分,es6之前函数语法一直没什么变化,遗留了许多问题,javaScript开发者多年来不断抱怨,es6终于决定大力度更新函数 ...
- python 全栈开发,Day88(csrf_exempt,ES6 快速入门,Vue)
BBS项目内容回顾 1. 登陆页面 1. 验证码 1. PIL(Pillow) 2. io 2. ORM 1. 增删改查 3. AJAX $.ajax({ url: '', type: '', dat ...
- ES6快速入门(二)数据结构
ES6快速入门 一.解构 1. 对象解构 let person = { name: 'Tang', age: 28 }; //必须同名,必须初始化 let {name, age} = person; ...
- ES6快速入门(一)函数与作用域
ES6快速入门 一.块级绑定 1.var声明与变量提升 使用var声明的变量,不论在何处都会被视为(声明)在函数级作用域顶部的位置发生. function getValue(condition) { ...
随机推荐
- HDU - 6761 Minimum Index (字符串,Lyndon分解)
Minimum Index 题意 求字符串所有前缀的所有后缀表示中字典序最小的位置集合,最终转换为1112进制表示.比如aab,有三个前缀分别为a,aa,aab.其中a的后缀只有一个a,位置下标1:a ...
- 【noi 2.6_9270】&【poj 2440】DNA(DP)
题意:问长度为L的所有01串中,有多少个不包含"101"和"111"的串. 解法:f[i][j]表示长度为i的01串中,结尾2位的十进制数是j的合法串的个数.那 ...
- hdu5437 Alisha’s Party
Problem Description Princess Alisha invites her friends to come to her birthday party. Each of her f ...
- Codeforces Round #643 (Div. 2) B. Young Explorers (思维,贪心)
题意:给你一组人\(a\),现在要将这些人进行分组,对于\(i\),只有某一组的人数\(\ge a_{i}\)时,\(i\)才可以加入这个组,问最多能够有多少组,(不必将所有人都选用). 题解:我们将 ...
- 11.PowerShell DSC之安装PowerShell Module
打开https://powershellgallery.com,检索你需要的目标模块,我们以安装名为"xmysql"的module为例: 自动安装 1.执行命令install-mo ...
- 5.2 spring5源码--spring AOP源码分析三---切面源码分析
一. AOP切面源码分析 源码分析分为三部分 1. 解析切面 2. 创建动态代理 3. 调用 源码的入口 源码分析的入口, 从注解开始: 组件的入口是一个注解, 比如启用AOP的注解@EnableAs ...
- 在kubernetes集群里集成Apollo配置中心(5)之dubbo服务消费者连接apollo实战
1.在Apollo的portal创建dubbo消费者项目 (1)添加dubbo消费者项目 (2)在dubbo消费者项目中添加配置项 (3)发布 2.通过jenkins构建dubbo消费者镜像 3.登录 ...
- 牛客网多校第5场 H subseq 【树状数组+离散化】
题目:戳这里 学习博客:戳这里 题意:给n个数为a1~an,找到字典序第k小的序列,输出该序列所有数所在位置. 解题思路:先把所有序列预处理出来,方法是设一个数组为dp,dp[i]表示以i为开头的序列 ...
- sizeof和strlen在string类中的使用
字符串的sizeof和strlen 考虑下面的问题: char a[] = "abcdef"; char b[20] = "abcdef"; string s ...
- JavaScript DOM操作之查找元素节点
概要: 编程接口 可通过 JavaScript 对 HTML DOM 进行访问. 所有 HTML 元素被定义为对象,而编程接口则是对象方法和对象属性. 方法是您能够执行的动作(比如添加或修改元素). ...