es6之let

2017-09-08  本文已影响0人  一枚靠脸吃饭的程序员

layout: post
title: es6之let
date: 2017-09-08 14:22:42
tags: 学习


概述

在写上一篇文章,关于cookie的操作时有一个demo,涉及到一个作用域的问题,实验了一下,然后又归纳小结了一波,主要还是参考阮大的es6入门,也算是面试经常问的问题,let和var的区别,之前都会回答块级作用域,具体一点的,申明提前,暂时性死区的都会大概提一提。想想还是好好梳理一下好了。

不存在变量提升

变量提升可以换一个词,在代码编译阶段做的申明提前操作。
随便看几个demo,和var的对比很容易看出来

console.log(a) // undefined
var a = 'var'

console.log(b) // 报错,b is not defined
let b = 'let'

那么再看一个demo,涉及到作用域的

var globalObj = {a:1}
var func = function() {
    console.log(globalObj)  //undefined
    globalObj.b = 2         //报错,cannot 'b' of undefined
    var globalObj = asdasd
}
console.log(globalObj)

虽然globalObj是全局作用域下,func也在里面,但是在内部局部的globalObj优先级高,虽然globalObj在内层是undefined也不影响。
今天在看犀牛书关于cookie操作的时候有个demo就有这个问题p591

暂时性死区

ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
继续用上一个demo,换成es6的版本,报的错不一样。
这么做个人感觉挺好,也算是一种规范,以前变量申明之前是可以用这个变量的,值是undefined,这样造成了很多意想不到的情况。
tips:typeOf方法也有可能报错啦

let globalObj = {a:1}
const func = () => {
    console.log(globalObj)  //Identifier 'globalObj' has already been declared
    globalObj.b = 2
    let globalObj = asdasd
}
console.log(globalObj)

不允许重复申明

var a = 1
var a = 2
let b = 3
let b = 4 // b报错, b has been declared

tip: 函数的形参也可以理解为申明了局部变量,所以也不能再次申明

块级作用域

先看一下函数作用域不好的地方

var tmp = new Date();
function f() {
  console.log(tmp);
  if (false) {
    var tmp = 'hello world';
  }
}
f(); // undefined

阮大给的这个demo挺nice的,f调用的时候本来是想tmp没有暴露到f的作用域下,引擎对tmp执行RHS查询,找到上一层作用域的tmp,但是if条件里面的逻辑没有形成作用域,tem在f函数中为局部变量。

var s = 'hello';

for (var i = 0; i < s.length; i++) {
  console.log(s[i]);
}

console.log(i); // 5

初学者写这种代码都没注意到内存泄露等问题,暴露过多的全局变量肯定是不好的。

上一篇下一篇

猜你喜欢

热点阅读