脚本宝典收集整理的这篇文章主要介绍了ES6学习之 -- let和const命令,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
-
let命令
用来声明变量,它的用法类似var,但是let命令声明的变量只在所在的代码块中有效。
{
VAR a = 1;
let b = 2;
}
console.LOG(a); // 1
console.log(b); // b is not defined b未定义
这就说明let定义的变量只在对应的代码块中有效。
同样的下面是个for循环
for(let i = 0; i < 5; i++){
// ...
}
console.log(i);// i is not defined i未定义
i只在循环体内有效。
阮一峰老师的文章中有一个例子我们看一下并且分析一下
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6
老师给我们的分析是这样子的:
上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。
如果还不理解的话我们可以再看一个例子:
var a = [];
for (let i = 0; i < 10; i++) {
let val = i;
a[i] = function () {
console.log(val);
};
}
a[6](); // 6
这时候你就会理解原因了,就相当于for循环中的执行体,每次的执行都位于一个单独的代码块中。这个val是我们显示定义的一个副本,当我们执行a[6]的时候,他会找到a[6]保存的函数的执行环境下去找这个val,数组a中的每个元素都位于一个单独的代码块中互不影响。那么我们可以得出一个结论:js引擎会为我们for循环中每次循环的代码块保存一个副本。
Nicholas C. Zakas
的《深入理解ES6》
中也有相关解释。
不存在变量提升
console.log(a);// undefined
console.log(b);// b is not defined
var a = 1;
let b = 2;
暂时性死区
只要块级作用域中存在let命令,那么let声明的变量就会绑定这个作用域不受外部影响。
var temp = 'hello';
if(true){
console.log(temp);// temp is not defined
let temp;
}
原因就是let绑定了块级作用域并且let定义的变量不会提升,就是这个地盘跟我同名的都得死。
隐蔽的死区
function test(x = y, y = 2) {
return [x, y];
}
test();// 报错
原因是:当执行test()的时候会先将y的值赋给x作为初始值,但此时y不存在,所以报错。
function test(x = 2, y = x) {
return [x, y];
}
test();// [2, 2]
这样就没问题了。
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
不允许重复声明
let不允许在同一作用域声明两个相同的变量。
let a;
var a;//报错 a已经被声明了
function fun(params) {
let params;
}
func();//报错 params已经被声明了
function test(params) {
{//内部代码块
let params;
}
}
test();//正常执行 执行函数内部的代码块被其中的那个变量占用了而已
块级作用域
先看一下es5,es5只有全局作用域和函数作用域。
var name = 'Jason';
function test() {
console.log(name);
if(false) {
var name = 'Nico';
}
}
==>相当于
var name = 'Jason';
function test() {
var name;//变量提升
console.log(name);
if(false) {
name = 'Nico';
}
}
所以执行test()会打印undefined
还有就是for循环的时候i的定义被提前
for(var i = 0; i < 3; i++) {
console.log(i);
}
console.log(i);
依次打印0 1 2 3
原因是i定义被提前,如下:
var i;
for(i = 0; i < 3; i++) {
console.log(i);
}
console.log(i);
es6出现了块级作用域
function test() {
let n = 0;
if(true) {
let n = 1;
}
console.log(n);
}
test();// 0
外层的块级作用域不受内层的控制。
{
{
let a = 1;
}
console.log(a);//报错 a未被定义
}
外层作用域无法访问内层作用域定义的变量
{
let a = 0;
{
let a = 1;
}
}
内层作用域可以命名外层已经命名的变量。
值得提醒的是函数在块级作用域中的声明
function test() {
console.log('outside');
}
(function() {
if(false) {
function test() {
console.log('inside');
}
}
console.log(test());
})();
ES5会打印inside字符串,ES6却会报test is not a function的错。
是不是很诧异,为什么ES6没有打印outside呢?
原因是:ES6中允许块级作用域中声明函数,但是函数声明会类似于var提升到全局作用域或者函数作用域头部,同时函数声明会提升到块级作用域头部,所以上面的代码就相当于
function test() {
console.log('outside');
}
(function() {
var test = undefined;
if(false) {
function test() {
console.log('inside');
}
}
console.log(test());
})();
所以才会报test is not a function的错误。
所以尽量避免块级作用域中声明函数,如果有必要的话可以使用函数表达式。
function test() {
console.log('outside');
}
(function() {
if(false) {
let test = function() {
console.log('inside');
}
}
console.log(test());// outside
})();
-
const命令
用于定义常量,一旦定义必须立刻初始化不然报错,定义后无法改变值,改变也会报错。
const USER_NAME;//报错
const USER_ID = '410100';
USER_ID = 2;//报错
const的作用域与let命令相同:只在声明所在的块级作用域内有效
const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用。
const声明的常量,也与let一样不可重复声明。
const其实保证的是变量存储的内存地址不得改动,对于简单的数据类型(数值,布尔,字符串),值就存在内存地址指向的位置,就等同于常量。但是对于数组、对象保存的就是一个指针,只能保证这个指针不被改变。对于内部的数据结构的变化是无法控制的。
const ARR = [];
ARR.push(1);// 可以执行
ARR.length = 0;// 可以执行
ARR = [];//报错
const OBJ = {};
OBJ.name = 'JASON';// 可以执行
OBJ = {};//报错
ES6 声明变量的六种方法:var
function
let
const
import
class
顶层对象:浏览器中指window Node中指global
ES5的时候全局变量的赋值与顶层变量的赋值是同一件事。
ES6改变了这一点除了var
与function
还保持原来的方式,新的声明变量的方法不再与顶层变量挂钩。
以上是脚本宝典为你收集整理的ES6学习之 -- let和const命令全部内容,希望文章能够帮你解决ES6学习之 -- let和const命令所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。