Let & Const

let 基础用法

很简单就能说明这个问题

if(false)
{
    var a = 'heihei'
}
a = undefined

if(true) {
    var a = 'heihei'
}
a = heihei

也就是说. { } 是木有作用域的.

里面声明的外面依然能够访问.

if(true) { let b = 'heihei_b' }
b = undefined

这样就有作用域了.

我想 w3c 如果不是为了兼容老代码。 可能直接强制用var 也遵循 代码块有作用域吧.

例子

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6]();  //6

这个是文章中的一个列子.

书中的解释是

上面代码中,变量ilet声明的,当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。

也就是说。 每一次都是一个新的循环,

对于新的循环来说 i 就是新的局部变量.

不存在变量提升

首先得明白什么是变量提升.

var a = 'haha';
(function() {
  alert(a)
})();

会弹出 haha

var a = 'haha';
(function() {
  var a = 'haha inside';
  alert(a);
})()

这个就是 haha inside 因为你调用的是局部变量 a.

var a = 'haha';
(function() {
  alert(a);
  var a = 'haha inside';
})()

这个时候弹出来 undefined

其实这段代码相当于

var a = 'haha';
(function() {
  var a;
  alert(a);
  a = 'haha inside';
})()

这个就是变量提升.

书中的不会存在变量提升就是指.

我不会弹出 undefined 哟.

我会报错. xxxx is not defined

就是这个意思.

暂时性死区

let 或 const 声明的变量拥有暂时性死区(TDZ):当进入它的作用域,它不能被访问(获取或设置)直到执行到达声明。

首先暂时性死区 就是变量提升的另一种说法.

var a = 'haha';
(function() {
  alert(a);
  var a = 'haha inside';
})()

这个之所以会弹出. undefined 是因为 var a = 'haha inside';

相当于在自执行函数顶部声明了一个 var a; 然后后面来赋值.

使用 let or const 你在声明之前使用会报错

不管你是否去 typeof

避免了 变量提升 的危险.

这个区域 就有一个吊炸天的名字 暂时性死区

本质就是叫你 别提莫 声明之前去使用.

不允许重复声明

var a = 1;
var a = 2;

var 可以重复声明。 谁后面声明用谁.

但是 let or const 不行.

不管对方使用的 var or let or const

以下情况都会报错

var a;
let a;

var b;
const b = '2';

let c;
var c;

const d = '2';
var d;

以上仅针对于同一级别的作用域。

块级作用域

以前 javascript 并没有块级作用域. 也就是说.

var a = 'b';
if(true)
    var a = 'c' 

a 等于 c

也就是说. 你 if 中声明的任何变量.

都将是和if同一层级的变量.

谈不上坑爹. 可是毕竟很多时候是需要块级作用域

要不也不用每次都写匿名自执行的函数

var a = (function(){ var a = ''; })();

难免会有污染的情况

还有书中说的.

for(var i=0;i<10;i++)
{

}

console.log(i); //10.

由于没有块级作用域. 所以泄露到了外部.

书中还提到了变量提升

var tmp = new Date();

function f() {
  console.log(tmp);
  if (false) {
    var tmp = "hello world";
  }
}

f(); // undefined

其实。 有良好的书写习惯的话 这种问题很少遇到.

当你使用 let or const 的时候就没有这种烦恼.

for(let i=0;i<10;i++)
{

}

console.log(i); // undefined

任意嵌套也没问题

for(let i=0;i<10;i++)
{
    if(true)
    {
        let i = 'wao';
    }

    console.log(i); // 1,2,3,4,5...
}

不同的 {} 就是一个作用域.

这引申出几个问题.

一. 是否是 {} 就是一个作用域。 switch case 呢?

function switchTest(o) {
    switch(o)
    {
      case '1':
        let a = '1';
        break;
      case '2':
        let a = '2';
        break;
    }
}

然后并不可以 直接报错.

Identifier 'a' has already been declared

继续来

function switchTest(o) {
    switch(o)
    {
      case '1':
        let a = '1';
        break;
      case '2':
        let b = '2';
        break;
    }

    console.log(a);
    console.log(b);
}

不管怎么都会报错.

因为变量死区.

就算你只输出一个 例如

console.log(a); //undefined

然而 真的有块级作用域

顺便提一句.

switch case 是一个很神奇的东西.

你在其中声明一样的变量,他会告诉你 变量已经声明过了. 一副我们里面是一起的样子

可是呢.

它和if有相同的功能.

如果没有 case 到. 那么里面代码也是不会执行.

如果你用var 该泄露还是泄露..

二. 书中提到的. function

首先书中提到了几个东西.

  1. es5 中不允许在 块级作用域 中声明函数
  2. es6 中. 允许声明,并且是类似 let 的行为,外部不能访问.

然而并没有声明卵用..

ES5. 浏览器没有遵守这个规定,还是支持在块级作用域之中声明函数。

而且 es5 & es6 混杂的情况下. 也很难按照规定来做.

以下是我测试. chrome 51.

目测只要执行过的 function 是不会遵循es6 let 声明.. 外部都能访问.

try {
  function f() {}
}
catch(e) { }

if (true) {
  function f() {}
}

都会影响外部.

如果不执行. 就没有这个问题.

如果在 function 中声明函数。 是不会影响外部的.

有点儿类似于 是声明的表达式.

可是有一个奇葩的

function f() { console.log('I am outside!'); }
(function () {
  if (false) {
    function f() { console.log('I am inside!'); }
  }

  f();
}());

按照我刚才的说法.

应该是执行 i am outside. 毕竟没有执行.

可是 ie9 是 I am inside! 如果在外部调用。 依然是 I am outside!'

chrome 是直接报错. 在外部 I am outside!'

然后茫然不知所措.

只能说各个浏览器,解析的方式各有不同.

考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,也应该写成函数表达式,而不是函数声明语句。

三. 块级作用域

之前突发奇想. 如果在一个里面,同事使用 let & var

是不是 外部能访问 b 不能访问 a

if(true) {
    var b = 'b';
    let a = 'a'
}

是可以的.

也就是说. 所谓的块级作用域其实和 {} 无关.

你必须使用 let 罢了

const

可以说他就是一个 固定的 let

const a;

你必须一开始就赋值. 不然会报错.

赋值以后,如果是值类型是不能更改的.

const a = 1;
a = 2

这样是会报错的.

可是引用类型就不一样了.

const 只能保证在 栈内存上的地址是不变的.

也就是说.

const a = {};
a['b'] = 'b';

这样是ok的.

内存地址不变,可是堆内存的实际的东西发生了变化.

如果你这样直接硬来是不行的。

const a = {};
a = {}

因为你这样是会改变地址的..

所以。

const 就用开放放字符串,数值吧.

全局对象的属性

如果你这样写.

var a = 'a'
console.log(window.a);

也就是说 var 在顶层声明会自动成为 window 属性.

但是 let 不会..

就是这样..

如果你用全部用 let

作用域就是 window -> 1层 -> 2层.

var

就是 (window & 1层) > 2层..

以上.

thx

02. Let & Const的更多相关文章

  1. ES6入门笔记

    ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...

  2. 我们为之奋斗过的C#-----C#的一个简单理解

    我们首先来简单叙述一下什么是.NET,以及C#的一个简单理解和他们俩的一个区别. 1 .NET概述 .NET是Microsoft.NET的简称,是基于Windows平台的一种技术.它包含了能在.NET ...

  3. Koa 框架教程

    Koa 框架教程   作者: 阮一峰 日期: 2017年8月 9日 Node 主要用在开发 Web 应用.这决定了使用 Node,往往离不开 Web 应用框架. Koa 就是一种简单好用的 Web 框 ...

  4. [React] 06 - Route: koa makes your life easier

    听说koa比express更傻瓜化,真的? Koa 框架教程 本身代码只有1000多行,所有功能都通过插件实现,很符合 Unix 哲学. 搭建简单服务器 Koa, 架设一个简单的服务器 // demo ...

  5. Koa框架教程

    Node主要用在开发 Web 应用.这决定了使用 Node,往往离不开 Web 应用框架. Koa 就是一种简单好用的 Web 框架.它的特点是优雅.简洁.表达力强.自由度高.本身代码只有1000多行 ...

  6. 深入剖析 linux GCC 4.4 的 STL string

    转自: 深入剖析 linux GCC 4.4 的 STL string 本文通过研究STL源码来剖析C++中标准模板块库std::string运行机理,重点研究了其中的引用计数和Copy-On-Wri ...

  7. string源码分析 ——转载 http://blogs.360.cn/360cloud/2012/11/26/linux-gcc-stl-string-in-depth/

    1. 问题提出 最近在我们的项目当中,出现了两次与使用string相关的问题. 1.1. 问题1:新代码引入的Bug 前一段时间有一个老项目来一个新需求,我们新增了一些代码逻辑来处理这个新需求.测试阶 ...

  8. 目标检测之harr---角点检测harr 的opencv实现

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...

  9. sizeof 感知重载,模板具现, 转换规则

    问题:如何侦知任意型别 T 是否可以自动转换为型别 U? 方案:侦测转换能力的想法:合并运用 sizeof 和重载函数. 1 依赖 sizeof,sizeof 有着惊人的能力,你可以把 sizeof  ...

随机推荐

  1. 【代码笔记】iOS-一个tableView,两个section

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  2. 分享iOS开发常用(三方类库,工具,高仿APP,实用网站,技术干货)

    一 . JSONModel  (三方类库会有更新,建议大家在线下载) http://pan.baidu.com/s/1i5ybP1z 二.AFNetworkiong http://pan.baidu. ...

  3. 基于SVN的项目管理——集中与分散

    我们在此处不讨论 GIT 比 SVN 好多少,也不讨论 Maven 和 Gradle 哪个好用,基于现有的开发环境,大多数公司还是采用 SVN + Maven 来进行项目管理——因为这已经满足了大多数 ...

  4. SQL Server 2012 新特性:服务角色管理

    数据库角色管理,已经可以使用alter role,create role和drop role. 2012增加了几个ddl语句,可以操作服务级别的角色管理,   CREATE SERVER ROLE 用 ...

  5. 如何评价一个RPC框架的性能

    协议:数据传输的格式,通信双方的契约.   传输:使用何种传输通道传输数据.   线程:接收到数据,如何分发数据进行处理.

  6. SSH批量部署服务

    SSH批量部署服务 1.1在NFS上作为中心分发服务器将私钥分发到其他服务器上 1.1.1NFS部署 [root@nfs-server ~]# useradd zhurui [root@nfs-ser ...

  7. monkey之monkey日志分析

    一.初步分析方法:Monkey测试出现错误后,一般的差错步骤为以下几步:1.找到是monkey里面的哪个地方出错2.查看Monkey里面出错前的一些事件动作,并手动执行该动作3.若以上步骤还不能找出, ...

  8. linux-关机出现Telling INIT to go to single user mode.无法关机

    运行/sbin/shutdown now最后显示:Telling INIT to go to single user mode.INIT:Going single userINIT:Sending g ...

  9. codevs 1052 地鼠游戏

    1052 地鼠游戏 http://codevs.cn/problem/1052/ 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不 ...

  10. November 1st 2016 Week 45th Tuesday

    Difficult circumstances serve as a textbook of life for people. 艰难坎坷是人们的生活教科书. It would be better if ...