【es6】 let & const

来源:互联网 发布:u盘安装ubuntu系统安装 编辑:程序博客网 时间:2024/04/29 22:31

let


对变量的声明

特性

  • let 只在命令所在代码块有效
  • 不存在变量提升
  • 区块中存在let const 会形成封闭作用域(在定义此之前使用typeof 会抛出 //ReferenceError)
  • 相同作用域不可重复声明(函数内部不可重新声明参数)

1.let 只在命令所在代码块有效

    {        let a = 10    }    a //a is not defined

for循环计数适合使用let命令,仅作用域有效,普通var声明会全局有效
2. let 不存在变量提升

    typeof a //"undefined"    typeof b //ReferenceError: b is not defined(报错)    let b = 1   

3.区块中存在let const 会形成封闭作用域(在变量声明前使用会报错,即“暂时性死区”)

    var o = 1    {        o = 2 //ReferenceError: o is not defined        let o    }
    function bar(x=y, y=2){}    bar() //ReferenceError: y is not defined(x=y,此时y还没有声明,属于“死区”)

4.相同作用域不可重复声明(函数内部不可重新声明参数)

    function(a) {        let a //报错        var b        let b //报错        {            let a //不报错        }    }

块级作用域

在es6之前存在两种作用域类型:

  • 全局作用域
  • 块级作用域
    由var声明的变量都存在变量提升
    es6使用let和const体现块级作用域,不存在变量提升,但在es6中var依旧存在变量提升

1.es5的问题

    var tmp = new Data()    function f() {      console.log(tmp);      if (false) {        var tmp = "hello world";  //变量提升,内层tmp变量覆盖外层tmp变量      }    }    f(); // undefined

2.es6的块级作用域

  • 外层作用域无法读取内层作用域的变量
  • 内层作用域可以定义外层作用域的同名变量
  • 块级作用域外部无法调用块级作用域内部定义的函数

针对函数

  1. es5中规定函数可在顶层作用域,函数作用域中声明,不可在块级作用域中声明,但声明了浏览器也支持
  2. es6可在块级作用域中声明,声明行为相当于let,外部不可访问,但浏览器有的不遵循~
'use strict';    if (true) {      function h() {return 0}    }    h() //Uncaught ReferenceError: h is not defined

es6的浏览器遵循如下规则

  • 函数声明类似于var,即会提升到全局作用域或函数作用域的头部。
  • 函数声明还会提升到所在的块级作用域的头部
所以    if (true) {      function h() {return 0}    }    h() //0 非严格模式下,不报错但是    if (false) {        function f() { console.log('I am inside!'); }    }    f(); //f is not a function因为相当于var变量提升后是这样的    var f = undefined;    if (false) {        function f() { console.log('I am inside!'); }    }    f(); //f is not a function
  1. let 实际为js新增了代码块级作用域,块级作用域中可声明函数(仅在大括号中有用)但在块级作用域之外不可使用 (要避免,必须时写成函数表达式)
  2. 严格模式下,函数只能在顶层作用域或者函数内声明,其他情况(比如if代码块,循环代码块)下声明会报错

const


特性

  • const声明只读常量,修改会报错,只声明不赋值也会报错
  • 不提升,同上存在暂时性死区,声明后才可用
  • 不可重复声明常量
  • 声明常量保存的是地址(即不能改变常量的指向,但可以改变其指向地址里的内容)
    const foo = {}    foo.prop = 123    foo.prop //123

const foo = Object.freeze( { } ) 可将对象冻结, 不可添加新属性。

    const foo = Object.freeze({})    foo.prop = 123 //添加新属性不起作用

但是上述方法,没有冻结对象里的所有属性,冻结对象里的所有属性:

    var constantize = (obj) => {        Object.freeze(obj)        Object.keys(obj).forEach( (key, value) => {            if(typeof obj[key] === 'object') {                constantize(obj[key])            }        })    }

跨模块常量

export 输出
import 引用

全局对象属性

  1. 浏览器全局对象是 window对象 ,全局对象的属性 == 全局变量
    a = 2    window.a //2
  1. var命令和function命令声明的全局变量,依旧是顶层对象的属性;另一方面规定,let命令、const命令、class命令声明的全局变量,不属于顶层对象的属性。
  2. 不是全局对象的属性返回undefined

其他

  1. do 关于使得块级作用域可以变为表达式,可以返回值
  2. 引入global作为顶层对象
原创粉丝点击