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 允许块级作用域的任意嵌套

  1. 外层作用域无法读取内层作用域的变量
  2. 内层作用域可以定义外层作用域的同名变量
  3. 块级作用域的出现,实际上使得立即执行(匿名)函数不再必要了。

块级作用域内声明的函数,行为类似于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 命令

基本用法

  1. 一旦声明,常量的值就不能改变。

    const声明的变量不得改变值,这意味着,==const一旦声明变量,就必须立即初始化==。
    ##### 本质:const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。引用类型数据结构不可变,但内部值可变。
  2. const的作用域与let命令相同:

    只在声明所在的块级作用域内有效。

  3. const命令声明的常量也是不提升,同样存在暂时性死区

    只能在声明的位置后面使用。

  4. 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,functionlet,const,import,class


本文来源个人对 阮一峰es6 总结,以供今后查阅。

以上是关于let const的主要内容,如果未能解决你的问题,请参考以下文章

ES6新特性之 let const

ES6 之 let和const块级作用域

P3 const 关键词 javascript

TypeScript 断言使用

Es6 学习笔记

JavaScript 中constvarlet 区别和使用