let与const

2019-05-19  本文已影响0人  Jay_ZJ

1 let

1.1 基本语法

1.用法类似于var,但声明变量只在所在代码块中有效。
2.非常适用于for循环
注:(1)for循环设置部分为负作用域,循环体为单独子作用域。
(2)var 声明 变量 i,变量提升,全局有效, 循环指向的是同一i,a[i]相同
(3)let 声明 变量i,变量不提升,作用于有效,循环指向新变量i,a[i]不同

1.2不存在变量提升

  1. var存在变量提升
  2. let不存在变量提升
    ...
    // let 的情况
    console.log(bar); // 报错 ReferenceError
    let bar = 2;
    ...

1.3暂时性死区(temporal dead zone,简称 TDZ)

1.块级作用域存在 let, 它所声明的变量 binding 这个区域,不受外部影响
在let命令声明变量tmp之前,都属于变量tmp的“死区”。
2.死区导致 typeof 可能出现错误

1.4 不允许重复声明

let不允许在相同作用域内,重复声明同一个变量

2. 块级作用域

2.1块级作用域的重要性

ES5只有 全局作用域 和 函数作用域,存在问题

  1. 内层变量可能覆盖外层变量
    2.用来计数的循环变量泄露成全局变量

2.2 ES6的块级作用域

  1. let为js新增块级作用域
  2. es6允许块级作用域的任意嵌套
  3. 内层作用域可以定义外层作用域的同名变量

2.3 块级作用域与函数声明

1.es5不允许函数在块级作用域声明,只能在顶层作用域和函数作用于之中声明
2.es6允许函数在块级作用域声明,行为类似于let,不可在快回作用域外引用。
注:在es6浏览器中:
(1) 允许在块级作用域内声明函数
(2) 函数声明类似于var,会提升到全局作用域或者函数作用于的头部
(3) 函数声明还会提升至所在的块级作用域的头部
(4) 避免在块级作用域内声明函数
(5) 如需实现(4),请写成函数表达式
(6) es6作用域必须要有大括号

3 const命令

2.1 基础用法

  1. const声明一个只读常量,声明后,值不变
  2. const只在声明所在的块级作用域内有效
  3. const命令声明的常量也是不提升,同样存在暂时性死区,只能在声明的位置后面使用
  4. const不可重复声明

2.2 本质

const实际上保证的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动

2.3 声明变量的六种方法

var function let const import class

4顶层对象的属性

  1. 浏览器顶层对象是 window 对象
  2. node 顶层对象是 global 对象
  3. ES5 顶层对象 与 全局变量是等价的
    存在问题:
    (1)编译时无法报出变量未声明的错误
    (2)程序员很容易不知不觉地就创建了全局变量
    (3)顶层对象的属性是到处可以读写的
    (4)window对象有实体含义,指的是浏览器的窗口对象,顶层对象是一个有实体含 义的对象,也是不合适的。
    4 解决:
    ES6 规定,
    (1)为保持兼容性,var命令和function命令声明的全局变量,依旧是顶层对象的属性;
    (2)let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。也就是说,从 ES6 开始,全局变量将逐步与顶层对象的属性脱钩。

5 globalThis对象

5.1 顶层对象不统一

(1)浏览器里面,顶层对象是window,但 Node 和 Web Worker 没有window。
(2)浏览器和 Web Worker 里面,self也指向顶层对象,但是 Node 没有self。
(3)Node 里面,顶层对象是global,但其他环境都不支持

5.2 用this取到顶层对象

(1)全局环境中,this会返回顶层对象。但是,Node 模块和 ES6 模块中,this返回的是当前模块。
(2)函数里面的this,如果函数不是作为对象的方法运行,而是单纯作为函数运行,this会指向顶层对象。但是,严格模式下,这时this会返回undefined。
(3)不管是严格模式,还是普通模式,new Function('return this')(),总是会返回全局对象。但是,如果浏览器用了 CSP(Content Security Policy,内容安全策略),那么eval、new Function这些方法都可能无法使用。

5.3 取到顶层对象的方法

// 方法一
(typeof window !== 'undefined'
? window
: (typeof process === 'object' &&
typeof require === 'function' &&
typeof global === 'object')
? global
: this);

// 方法二
var getGlobal = function () {
if (typeof self !== 'undefined') { return self; }
if (typeof window !== 'undefined') { return window; }
if (typeof global !== 'undefined') { return global; }
throw new Error('unable to locate global object');
};

5.4 globalThis提案

引入globalThis作为顶层对象

上一篇 下一篇

猜你喜欢

热点阅读