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

栏目: JavaScript · 发布时间: 5年前

内容简介:<深入理解ES6>一书中,提起 let/const 这也是平常工作用的比较多,最近需要给公司做培训. 重新复习下以往的知识点.本文首发自再聊

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

本文首发自 github 个人博客 . 转载请注明出处. 来这里讨论

let/const

再聊 let/const 之前, 让我们回顾下我们的老朋友 var , 他有什么特点或特性

var

通过下面的例子, 可以复习下, 关键字 var 声明带来的影响.

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只声明,未赋值,函数已声明且赋值.

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

由此可见 var声明 会带来以下影响

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

通常的习惯可能是, 放在 top scope 的位置, 作为一个规范来约束自己或团队.

但并不是每个人都能很好的按照规范来做, 于是ES6 推出了 let/const来解决 var声明 的弊端

let/const

把上面的代码换成 let

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);
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Linux Programming Interface

The Linux Programming Interface

Michael Kerrisk / No Starch Press / 2010-11-6 / GBP 79.99

The Linux Programming Interface describes the Linux API (application programming interface)-the system calls, library functions, and other low-level interfaces that are used, directly or indirectly, b......一起来看看 《The Linux Programming Interface》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具