let
和const
是 ES6 新增的敕令,用于声明变量,这两个敕令跟 ES5 的var
有许多差别,而且let
和const
也有一些纤细的差别,再仔细阅读了阮一峰先生的文档后,发明照样有一些不知道的细节…
内容:
var
和let
/const
的区分
- 块级作用域
- 不存在变量提拔
- 暂时性死区
- 不可反复声明
- let、const声明的全局变量不会挂在顶层对象下面
const
敕令两个注重点:
- const 声明以后必需立时赋值,不然会报错
- const 简朴范例一旦声明就不能再变动,庞杂范例(数组、对象等)指针指向的地点不能变动,内部数据能够变动。
为何须要块级作用域?
ES5只需全局作用域和函数作用域,没有块级作用域。
这带来许多不合理的场景:
- 内层变量能够掩盖外层变量
- 用来计数的轮回变量泄漏为全局变量
var tmp = new Date();
function f() {
console.log(tmp); // 想打印外层的时刻作用域
if (false) {
var tmp = 'hello world'; // 这里声明的作用域为全部函数
}
}
f(); // undefined
var s = 'hello';
for (var i = 0; i < s.length; i++) {
console.log(s[i]); // i应当为此次for轮回运用的变量
}
console.log(i); // 5 全局局限都能够读到
块级作用域
- 作用域
function f1() {
let n = 5;
if (true) {
let n = 10;
console.log(n); // 10 内层的n
}
console.log(n); // 5 当前层的n
}
- 块级作用域恣意嵌套
{{{{
{let insane = 'Hello World'}
console.log(insane); // 报错 读不到子作用域的变量
}}}};
- 块级作用域真正使代码支解成块了
{
let a = ...;
...
}
{
let a = ...;
...
}
以上情势,能够用于测试一些主意,不必忧郁变量重名,也不必忧郁外界滋扰
块级作用域声明函数:
在块级作用域声明函数,由于浏览器的要兼容老代码,会发生一些
题目!
在块级作用域声明函数,最好运用匿名函数的情势。
if(true){
let a = function () {}; // 作用域为块级 令声明的函数作用域局限更清楚
}
ES6 的块级作用域许可声明函数的划定规矩,只在运用大括号的状况下建立,假如没有运用大括号,就会报错。
// 报错
'use strict';
if (true)
function f() {} // 我们须要给if加个{}
不存在变量提拔
变量提拔的征象:在统一作用域下,变量能够在声明之前运用,值为 undefined
ES5 时运用var
声明变量,常常会涌现变量提拔的征象。
// var 的状况
console.log(foo); // 输出undefined
var foo = 2;
// let 的状况
console.log(bar); // 报错ReferenceError
let bar = 2;
暂时性死区:
只需一进入当前作用域,所要运用的变量就已存在了,然则不可猎取,只需比及声明变量的那一行代码涌现,才能够猎取和运用该变量
var tmp = 123; // 声明
if (true) {
tmp = 'abc'; // 报错 由于本地区有tmp声明变量
let tmp; // 绑定if这个块级的作用域 不能涌现tmp变量
}
暂时性死区和不能变量提拔的意义在于:
为了削减运行时毛病,防备在变量声明前就运用这个变量,从而致使意料之外的行动。
不许可反复声明变量
在测试时涌现这类状况:
var a= '声明';const a = '不报错'
,这类状况是由于babel在转化的时刻,做了一些处置惩罚,在浏览器的掌握台中测试,就胜利报错
let
、const
不许可在雷同作用域内,反复声明统一个变量
function func(arg) {
let arg; // 报错
}
function func(arg) {
{
let arg; // 不报错
}
}
let、const声明的全局变量不会挂在顶层对象下面
- 浏览器环境顶层对象是:
window
- node环境顶层对象是:
global
- var声明的全局变量会挂在顶层对象下面,而let、const不会挂在顶层对象下面。以下面这个栗子
var a = 1;
// 假如在 Node环境,能够写成 global.a
// 或许采纳通用要领,写成 this.a
window.a // 1
let b = 1;
window.b // undefined
const敕令
一旦声明,必需立时赋值
let p; var p1; // 不报错 const p3 = '立时赋值' const p3; // 报错 没有赋值
const一旦声明值就不能转变
简朴范例:不能修改
const p = '不能转变'; p = '报错'
庞杂范例:变量指针不能变
斟酌以下状况:
const p = ['不能修改'] const p2 = { name: 'OBKoro1' } p[0] = '不报错' p2.name = '不报错' p = ['报错'] p2 = { name: '报错' }
const所说的一旦声明值就不能转变,实际上指的是:变量指向的谁人内存地点所保留的数据不得修改
- 简朴范例(number、string、boolean):内存地点就是值,即常量(一变就报错).
- 庞杂范例(对象、数组等):地点保留的是一个指针,
const
只能保证指针是牢固的(老是指向统一个地点),它内部的值是能够转变的(不要认为const就平安了!)所以只需不从新赋值全部数组/对象, 由于保留的是一个指针,所以对数组运用的
push
、shift
、splice
等要领也是许可的,你就是把值一个一个全都删光了都不会报错。
> 庞杂范例另有函数,正则等,这点也要注重一下。
总结:
再总结一下,看到这些名词,脑子里应当会有对应的明白,假如没有的话,那能够再看看对应的内容。
var
和let
/const
的区分:
- 块级作用域
- 不存在变量提拔
- 暂时性死区
- 不可反复声明
- let、const声明的全局变量不会挂在顶层对象下面
const
敕令两个注重点:
-
let
能够先声明稍后再赋值,而const
在 声明以后必需立时赋值,不然会报错 - const 简朴范例一旦声明就不能再变动,庞杂范例(数组、对象等)指针指向的地点不能变动,内部数据能够变动。
let、const运用场景:
-
let
运用场景:变量,用以替换var
。 -
const
运用场景:常量、声明匿名函数、箭头函数的时刻。
勉励我一下:
以为还不错的话,给我的项目点个star吧
参考资料: