02. Let & Const
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
这个是文章中的一个列子.
书中的解释是
上面代码中,变量
i
是let
声明的,当前的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
首先书中提到了几个东西.
- es5 中不允许在 块级作用域 中声明函数
- 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的更多相关文章
- ES6入门笔记
ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...
- 我们为之奋斗过的C#-----C#的一个简单理解
我们首先来简单叙述一下什么是.NET,以及C#的一个简单理解和他们俩的一个区别. 1 .NET概述 .NET是Microsoft.NET的简称,是基于Windows平台的一种技术.它包含了能在.NET ...
- Koa 框架教程
Koa 框架教程 作者: 阮一峰 日期: 2017年8月 9日 Node 主要用在开发 Web 应用.这决定了使用 Node,往往离不开 Web 应用框架. Koa 就是一种简单好用的 Web 框 ...
- [React] 06 - Route: koa makes your life easier
听说koa比express更傻瓜化,真的? Koa 框架教程 本身代码只有1000多行,所有功能都通过插件实现,很符合 Unix 哲学. 搭建简单服务器 Koa, 架设一个简单的服务器 // demo ...
- Koa框架教程
Node主要用在开发 Web 应用.这决定了使用 Node,往往离不开 Web 应用框架. Koa 就是一种简单好用的 Web 框架.它的特点是优雅.简洁.表达力强.自由度高.本身代码只有1000多行 ...
- 深入剖析 linux GCC 4.4 的 STL string
转自: 深入剖析 linux GCC 4.4 的 STL string 本文通过研究STL源码来剖析C++中标准模板块库std::string运行机理,重点研究了其中的引用计数和Copy-On-Wri ...
- string源码分析 ——转载 http://blogs.360.cn/360cloud/2012/11/26/linux-gcc-stl-string-in-depth/
1. 问题提出 最近在我们的项目当中,出现了两次与使用string相关的问题. 1.1. 问题1:新代码引入的Bug 前一段时间有一个老项目来一个新需求,我们新增了一些代码逻辑来处理这个新需求.测试阶 ...
- 目标检测之harr---角点检测harr 的opencv实现
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/29356187 作者:毛星云(浅墨) ...
- sizeof 感知重载,模板具现, 转换规则
问题:如何侦知任意型别 T 是否可以自动转换为型别 U? 方案:侦测转换能力的想法:合并运用 sizeof 和重载函数. 1 依赖 sizeof,sizeof 有着惊人的能力,你可以把 sizeof ...
随机推荐
- 如何解决MSI类型的Sharepoint Server2016 安装即点即用的office 2016 plus问题
前提 在sharepoint server 2016安装office 2016 plus提示如下错误: 解决方法 Ø 概念 1. 即点和即用的概念:即点即用是一种通过 Internet 安装和更新 O ...
- 利用私有的API获得手机上所安装的所有应用信息(包括版本,名称,bundleID,类型)
MobileCoreService这个系统的库,里面有个私有的类LSApplicationWorkspace ,利用运行时可以获得私有类里面的方法,- (id)allInstalledApplicat ...
- Android Weekly Notes Issue #222
Android Weekly Issue #222 September 11th, 2016 Android Weekly Issue #222 ARTICLES & TUTORIALS Fo ...
- swift学习笔记1——基础部分
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- [Erlang 0128] Term sharing in Erlang/OTP 下篇
继续昨天的话题,昨天提到io:format对数据共享的间接影响,如果是下面两种情况恐怕更容易成为"坑", 呃,恰好我都遇到过; 如果是测试代码是下面这样,得到的结果会是怎样?猜! ...
- java中数据类型的转换
数据类型的转换,分为自动转换和强制转换. 自动转换是程序执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换 强制转换必须在代码中声明,转换顺序不受限制 自动数据类 ...
- 在Ubuntu中建立MySQL数据库
最近在做一个关于云计算安全系统的项目,需要用到MySQL数据库,现在把建立数据库的步骤记录下来. 一.用命令在Ubuntu上安装MySQL # sudo apt-get update # sudo a ...
- zabbix完整安装
一.nginx安装 1.必要软件准备: 为了支持rewrite功能,我们需要安装pcre: yum install pcre-* 需要ssl的支持,如果不需要ssl支持,请跳过这一步: yum ins ...
- 《Note --- Unreal 4 --- PersonaHowToMovement》
https://docs.unrealengine.com/latest/CHN/Gameplay/HowTo/CharacterMovement/index.html 这里的demo是按照一些per ...
- 由Photoshop高反差保留算法原理联想到的一些图像增强算法。
关于高反差保留的用处说明呢,从百度里复制了一段文字,我觉得写得蛮好的: 高反差保留就是保留图像的高反差部分,再说得真白些,就是保留图像上像素与周围反差比较大的部分,其它的部分都变为灰色.拿一个人物照片 ...