这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战。
前言
ECMAScript 6.0 简称ES6 , 是 JavaScript 语言的新一代的标准,于在 2015 年 6 月发布,正式名称就是《ECMAScript 2015 标准》。
一般情况,ES6 一个泛指, 5.1版以后的 JavaScript 的下一代标准,涵盖了 ES2015、ES2016、ES2017、ES2018、ES2019、ES2020、ES2021 等等
let 申明
在ES6之前,申明变量有两种方式,一种是var, 一种是非严格模式,直接赋值。
var a = 10;
function log(){
b = 20;
}
log()
console.log(a) // 10
console.log(b) // 20
let与var非常相似,但是在let命令所在的代码块内有效, 并且不能重复申明。
同一作用域不能重复申明
同一作用域,下面的例子var申明可以重复,let却不可以。
var a = 1;
var a = 1;
var b = 1;
let b = 1;
// Uncaught SyntaxError: Identifier 'a' has already been declared
代码块内有效
ES6新增了代码块,let与const的申明仅仅在代码块中有效。
{
var a = 1;
let b = 1;
}
console.log(a);
console.log(b);
// Uncaught ReferenceError: b is not defined
不存在变量提升
变量提升 : 变量可以在声明之前使用,值为undefined。
之前的var存在变量提升,而let不存在此现象。
console.log(a); // undefined
console.log(b); // VM39:2 Uncaught ReferenceError: b is not defined
var a = 1
let b = 1
暂时性死区
块级作用域内let申明,不再受外部的影响。会导在块级作用域内申明之前不可以被访问, 这就是暂时性死区。
先来一个简单的例子。
var a = 10;
function log(){
console.log(a);
let a = {};
}
log();
再来一个嵌套级别多一点的例子:
function log(msg){
var prefix = "log:";
function innerLog(){
console.log(prefix + msg);
let prefix = "innerLog";
}
innerLog();
}
一个经典闭包的例子
<div id="buttons">
<button class="button">按钮1</button>
<button class="button">按钮2</button>
<button class="button">按钮3</button>
<button class="button">按钮4</button>
<button class="button">按钮5</button>
</div>
<script>
var buttonsEl = document.getElementById("buttons");
for (var i = 0; i < buttonsEl.children.length; i++) {
buttonsEl.children[i].onclick = function () {
console.log(i);
};
}
</script>
五个按钮,按个加上点击事件,点击时输出i的值,你会发现,无论是点击那个按钮,输出都会是 5。
这是闭包作怪,最经典的解决方案,就是
- IIFE
- let
let为什么能解决这个问题,大家可能还会存在疑问,这不是还能访问到吗?
这里啊,其实 for语句和循环体{}是两个不同的作用域。
我们可以看到{}申明let i,被没有报错。
for (let i = 0; i <= 2; i++) {
let i = 1000;
console.log(i);
}
// 1000
// 1000
更多关于 for let循环可以单独出一片文章讲解。
const 申明
const 申明可以认为是let的进一步的增强,一旦声明,常量的值就不能改变。
const NUM = 10;
NUM = 20;
如果其值是一个对象,值不能被直接替换,但是其属性依旧是可以更改的。
const person = {
name: "tome",
age: 10
}
person.name = "Jim"
person = {
name: "tom",
age: 10
}
// Uncaught TypeError: Assignment to constant variable.
所以const的本质: 并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。
- 基础类型变量的值
数据的地址 - 引用类型变量的值
一个指向实际数据的指针
小结
今天你收获了吗?