let const
Posted topyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了let const相关的知识,希望对你有一定的参考价值。
let 和 const 命令
1. let命令
基础使用
let声明的变量只在它所在的代码块有效。
var a = [];
for (let i = 0; i < 10; i++)
a[i] = function ()
console.log(i);
;
a[6](); // 6
上面代码中,变量i是let声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量.
另外,==for循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域==。
不存在变量提升
console.log(bar); // 报错ReferenceError
let bar = 2;
暂时性死区 (temporal dead zone,简称 TDZ)
只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。
var tmp = 123;
if (true)
// TDZ开始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ结束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
使用let和const命令声明变量之前,该变量都是不可用的,从一开始就形成了封闭作用域。==凡是在声明之前就使用这些变量,就会报错.==
不允许重复声明
let不允许在相同作用域内,重复声明同一个变量。
function func(arg)
let arg; // 报错
function func(arg)
let arg; // 不报错
2.块级作用域
ES6 允许块级作用域的任意嵌套
- 外层作用域无法读取内层作用域的变量
- 内层作用域可以定义外层作用域的同名变量
- 块级作用域的出现,实际上使得立即执行(匿名)函数不再必要了。
块级作用域内声明的函数,行为类似于var声明的变量。
ES6 引入了块级作用域,明确允许在块级作用域之中声明函数。ES6 规定,块级作用域之中,函数声明语句的行为类似于let,在块级作用域之外不可引用。
ES6 在附录 B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
- 允许在块级作用域内声明函数。
- 函数声明类似于var,即会提升到全局作用域或函数作用域的头部(名提升,值留在原地)。
- 同时,函数声明还会提升到所在的块级作用域的头部。
根据这三条规则,==在浏览器的ES6环境中,块级作用域内声明的函数,行为类似于var声明的变量。==
function f() console.log('I am outside!');
(function ()
if (false)
// 重复声明一次函数f
function f() console.log('I am inside!');
f();
());
/** ES5 环境 **/
function f() console.log('I am outside!');
(function ()
function f() console.log('I am inside!');
if (false)
f();
());
/** 浏览器的 ES6 环境 **/
function f() console.log('I am outside!');
(function ()
var f = undefined;
if (false)
function f() console.log('I am inside!');
f();
());
// Uncaught TypeError: f is not a function
ES6 的块级作用域允许声明函数的规则,只在使用大括号的情况下成立,如果没有使用大括号,就会报错。
// 报错
'use strict';
if (true)
function f()
do 表达式
本质上,块级作用域是一个语句,将多个操作封装在一起,没有返回值
let t = f();
t = t * t + 1;
//在块级作用域以外,没有办法得到t的值,因为块级作用域不返回值,除非t是全局变量
在块级作用域之前加上do(变为do表达式),就会==返回内部最后执行的表达式的值==。
let x = do
let t = f();
t * t + 1;
;
//变量x会得到整个块级作用域的返回值(t * t + 1)
3.const 命令
基本用法
一旦声明,常量的值就不能改变。
const声明的变量不得改变值,这意味着,==const一旦声明变量,就必须立即初始化==。
##### 本质:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。引用类型数据结构不可变,但内部值可变。const的作用域与let命令相同:
只在声明所在的块级作用域内有效。
const命令声明的常量也是不提升,同样存在暂时性死区
只能在声明的位置后面使用。
const声明的常量,也与let一样不可重复声明
用let声明过的变量,也不可在用const声明
如果真的想将对象冻结,应该使用Object.freeze方法
const foo = Object.freeze();
// 常规模式时,下面一行不起作用;
// 严格模式时,该行会报错
foo.prop = 123;
除了将对象本身冻结,对象的属性(也可能是对象)也应该冻结。下面是一个将对象彻底冻结的函数。
var constantize = (obj) =>
Object.freeze(obj);
Object.keys(obj).forEach( (key, i) =>
if ( typeof obj[key] === 'object' )
constantize( obj[key] );
);
;
ES6 声明变量的六种方法:
var
,function
和let
,const
,import
,class
本文来源个人对 阮一峰es6 总结,以供今后查阅。
以上是关于let const的主要内容,如果未能解决你的问题,请参考以下文章