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 ...
随机推荐
- 原创 C++应用程序在Windows下的编译、链接:第三部分 静态链接(二)
3.5.2动态链接库的创建 3.5.2.1动态链接库的创建流程 动态链接库的创建流程如下图所示: 在系统设计阶段,主要的设计内容包括:类结构的设计以及功能类之间的关系,动态链接库的接口.在动态链接库中 ...
- 微信app支付 ci框架做的
/** * 组合微信app支付 获得prepayid * @param int $order_num */ private function _wxpay_reques ...
- Unity 重要基础知识点
这是两个月前的学习记录,发出来了下,如果有误欢迎大家指出: 脚本生命周期 //每当脚本被加载时调用一次 // 1. 在Awake中做一些初始化操作 void Awake(){ //初始化publi ...
- 初始webservice
webservice 可以用来查天气,以及手机号码类型等功能,这写都是简单的 方法有很多: 1.通过创建 web service exploer 创建出一个web services explorer ...
- Duplicate entry 'javajavajav' for key 'username'
org.apache.ibatis.exceptions.PersistenceException: ### Error updating database. Cause: com.mysql.jd ...
- python-进程&线程
进程(process):相当于一个程序要运行时所需的所有资源的集合,相当于一个车间,不工作 两个进程之间的数据不共享,完全不独立,互相不能访问. 线程(thread):一道单一指令的控制流,寄生在进程 ...
- python读取excel一例-------从工资表逐行提取信息
在工作中经常要用到python操作excel,比如笔者公司中一个人事MM在发工资单的时候,需要从几百行的excel表中逐条的粘出信息,然后逐个的发送到员工的邮箱中.人事MM对此事不胜其烦,终于在某天请 ...
- mysql中间件atlas配置使用
MySQL所在机器: 192.168.16.70(Master) 192.168.16.74(Slave) 192.168.16.72(atlas)注意:主从复制需要自行配置atlas配置使 ...
- 第六次团队作业——Alpha冲刺之事后诸葛亮
Deadline:2016-11-24 22:00pm Alpha冲刺,很多同学经历了"Learning by doing"的学一门新的编程语言.学Git.学做一个完整的项目.但是 ...
- 日货EmEditor的使用小技巧
1.查看->大纲向导,可层级显示HTML 2.工具->插件->资源管理器,可在左侧显示资源管理器 3.工具->插件->单词自动完成,可实现单词智能提示功能