<深刻理解ES6>一书中,提起 let/const 这也是日常工做用的比较多,最近须要给公司作培训. 从新复习下以往的知识点.javascript
本文首发自 github 我的博客. 转载请注明出处. 来这里讨论前端
再聊 let/const
以前, 让咱们回顾下咱们的老朋友 var
, 他有什么特色或特性java
经过下面的例子, 能够复习下, 关键字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
app
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.a
和a
相等. 产生上面现象的缘由是什么呢??
在let/const
声明前访问其变量会形成初始化以前不能访问
,这种现象叫作 TDZ.
上述例子中, a
和Date
声明后并无污染 window.a
和window.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 对对象处理的时候, 对象/数组属性赋值还能够修改.
关于对象的常量问题, 放到后面章节整理.