[深刻理解ES6]let/const/var

<深刻理解ES6>一书中,提起 let/const 这也是日常工做用的比较多,最近须要给公司作培训. 从新复习下以往的知识点.javascript

本文首发自 github 我的博客. 转载请注明出处. 来这里讨论前端

let/const

再聊 let/const以前, 让咱们回顾下咱们的老朋友 var, 他有什么特色或特性java

var

经过下面的例子, 能够复习下, 关键字var声明带来的影响.node

console.log(typeof A) // 'function'
console.log(a) // undefined
console.log(typeof a) // 'undefined'
console.log(typeof Date) // 'function'
console.log(window.Date) // function Date() {}
function A() {
    console.log(new Date())
}
var a = 10
var Date = 1000
console.log(window.Date) // 1000
复制代码

因为变量提高的缘故, function 优先于 var提高且定义,此时 a只声明,未赋值,函数已声明且赋值.git

一样的代码,把window改为global放在node里面运行发现结果又不同, global.Date没有被从新赋值, 是由于在node运行环境里面, node 出于代码安全考虑, 每个文件最终变成了由 require('module').wrapper方法包裹起来, 每个node的 js 文件, 须要 经过exports或module.exports暴露出模块的方法和属性才能使用.github

因而可知 var声明会带来如下影响面试

  • 变量提高 (一不当心就掉坑, 非前端开发者会很郁闷)
  • 会覆盖/污染 (当前)做用域的变量

一般的习惯多是, 放在 top scope 的位置, 做为一个规范来约束本身或团队.数组

但并非每一个人都能很好的按照规范来作, 因而ES6 推出了 let/const来解决var声明的弊端安全

let/const

把上面的代码换成 letapp

console.log(a) // Uncaught ReferenceError: Cannot access 'a' before initialization
console.log(typeof a) // 'undefined'
console.log(typeof Date) // 'function'
console.log(window.Date) // function Date() {}
复制代码

以前执行的 console.log(a) 直接报错, 阻止程序运行.

直接运行console.log(typeof a) 也同样, 而不作任何声明的时候, 会输出 'undefined'.

let a = 10
let Date = 1000
console.log(window.Date) // function Date() {}
console.log(a) // 10
console.log(Date) // 1000
console.log(window.a) // undefined
复制代码

正常逻辑执行后, 并无想象中, window.aa相等. 产生上面现象的缘由是什么呢??

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

let/const声明前访问其变量会形成初始化以前不能访问,这种现象叫作 TDZ.

let/const不会对 scope 域名作覆盖/污染

上述例子中, aDate声明后并无污染 window.awindow.Date, 所以当使用的时候须要覆盖的时候使用 let/const 声明的变量, 须要手动覆盖.

循环中造成新的块级绑定

早年有一个经典的面试题, 叫作 建立10 个 div.点击输出对应的索引.

笔者在初次写 js 的时候, 写成了这种错误形式

// bad way
for(var i = 0; i < 10; i++) {
    var div = document.createElement('div')
    div.className = 'item'
    div.innerHTML = i
    div.onclick = function() {
        alert(i)
    }
    document.body.appendChild(div)
}
复制代码

输出的结果也每每是 10, 需求是点击索引啊. 形成这种结果的缘由是

var变量提高, 当点击的时候此时 i 是 10

所以咱们经常用 IIFE(即时执行函数)

// good way
for(var i = 0; i < 10; i++) {
    var div = document.createElement('div')
    div.className = 'item'
    div.innerHTML = i
    div.onclick = (function(i) {
        return function() {
            alert(i)
        }
    })(i)
    document.body.appendChild(div)
}
复制代码

那有木有更好的方案, 能不能每次 循环的时候建立一个新的 i, let具有这一特性

// better way
for (let i = 0; i < 10; i++) {
    let div = document.createElement("div");
    div.className = "item";
    div.innerHTML = i;
    div.onclick = function() {
        alert(i)
    }
    document.body.appendChild(div);
}
复制代码

其余

const用来保存常量, let 在修改的使用. const 对对象处理的时候, 对象/数组属性赋值还能够修改.

关于对象的常量问题, 放到后面章节整理.

相关文章
相关标签/搜索