惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
Y
Y Combinator Blog
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
Martin Fowler
Martin Fowler
博客园_首页
大猫的无限游戏
大猫的无限游戏
美团技术团队
S
SegmentFault 最新的问题
T
The Blog of Author Tim Ferriss
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
MyScale Blog
MyScale Blog
小众软件
小众软件
Vercel News
Vercel News
阮一峰的网络日志
阮一峰的网络日志
N
Netflix TechBlog - Medium
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
量子位
博客园 - 【当耐特】
J
Java Code Geeks
F
Fortinet All Blogs
宝玉的分享
宝玉的分享
Stack Overflow Blog
Stack Overflow Blog
博客园 - 司徒正美

博客园 - 敏捷的水

程序员成长思维:把自己当做产品来发展 发展你的兴趣,而不是跟随你的兴趣 领导力:不要做个“好人” 当你是个锤子 做自己的CEO 我们为何难以升职加薪 程序员的自我修养系列(四):图形化表达 - 敏捷的水 - 博客园 程序员的自我修养系列(三):习惯付费 程序员的自我修养系列(二):从元编程到元认知 程序员的自我修养系列(一):聊聊专业和业余 如何向别人介绍我是一个程序员 领域驱动开发实践之路:我们是如何从领域驱动开发当中获益的 ES6+ 现在就用系列(一):为什么使用ES6+ - 敏捷的水 - 博客园 程序员之网络安全系列(六):动态密码 程序员之网络安全系列(五):数字证书以及12306的证书问题 程序员之网络安全系列(四):数据加密之非对称秘钥 程序员之网络安全系列(三):数据加密之对称加密算法 程序员之网络安全系列(二):如何安全保存用户密码及哈希算法 程序员之网络安全系列(一):为什么要关注网络安全?
ES6+ 现在就用系列(二):let 命令
敏捷的水 · 2016-01-25 · via 博客园 - 敏捷的水

2016-01-25 16:33  敏捷的水  阅读(4224)  评论()    收藏  举报

系列目录

ES6+ 现在就用系列(一):为什么使用ES6+
ES6+ 现在就用系列(二):let 命令
ES6+ 现在就用系列(三):const 命令
ES6+ 现在就用系列(四):箭头函数 =>
ES6+ 现在就用系列(五):模板字面量 (Template Literals)
ES6+ 现在就用系列(六):解构赋值 (Destructuring )
ES6+ 现在就用系列(七):Promise
ES6+ 现在就用系列(八):类 (Class),继承,对象的扩展
ES6+ 现在就用系列(九):模块
ES6+ 现在就用系列(十):Async 异步编程
ES6+ 现在就用系列(十一):ES7 Async in Browser Today

ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。也就是有了块级作用域。

为什么需要块级作用域?

避免 var 变量提升带来的副作用

示例:

var saleCount = 20;

function f(){
console.log(saleCount);
if(saleCount<100)
{
// according some rule, change it to 100
var saleCount=60;
console.log(saleCount);
}
}

f()

输出: // undefined

因为 "var saleCount=60;" 作用域是整个函数,而JavaScript里var定义的变量存在变量提升,也就是console.log(saleCount), 这个saleCount是 "var saleCount=60;" 这一句定义的,当调用的时候,saleCount的值是undefined. 实际上等于下面代码。

var saleCount = 20;

function f(){

var saleCount;
console.log(saleCount);
if(saleCount<100)
{
// according some rule, change it to 100
saleCount=60;
console.log(saleCount);
}

}

f() // undefined

避免循环变量变为全局变量

示例:

for (var i = 0; i < 10; i++){
// do something
}

console.log(i);
输出: 10

很明显,我们不希望i,这个变量变为全局变量。

let 示例代码

'use strict'
{
var b=1;
let a=2;
}

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

输出: ReferenceError: a is not defined

上一节我们给出了如下的示例:

var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a1;
a2;
a3;

输出: 10,10,10

我们看到,输出的结果不是我们想要的,因为i是用var定义的,那么他在全局范围内都是生效的,也就是我们循环结束以后,i的值就是10,那么不管调用数组的那个元素,console.log(i) 输出的都是10, 那么let因为有了块级作用域,就可以避免这个问题。

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

输出 1, 2,3

另外,函数本身的作用域也在定义他的块的作用域内。

function hello(){console.log("Hello, Jack")};

{
function hello(){console.log("Hello, Tom")};
}

hello();

上面的代码在ES6里面输出了"Hello, Jack", 而在ES5里输出了"Hello, Tom".

注意事项

不能先使用,后定义

console.log(x);
console.log(y);

var x = 1;
let y = 2;

输出

undefined
ReferenceError: y is not defined

上面的代码由于x是var定义的,一开始x的变量是存在的,只是值是undefined, 但是由于y 是let定义的,就不存在变量提升。

暂时性死区

如果一个变量是使用let定义的,那么这个变量就属于声明时所在的代码块,也就是变量不再受外部影响,下面的a 由于在块里定义了,所以 会报错,因为在那个块里是先使用后定义,如果去掉“let a”, 那么a就是外部的变量,这个时候就不会出错。

var a = "hello";

{
a = 'world';
let a;
}

// ReferenceError

不能重复申明

也就是不能重复申明同一个变量,即使一个是let申明,一个是用var申明也不行。 下面的代码都会报错。

function () {
let a = 10;
var a = 1;
}

function () {
let b = 10;
let b = 1;
}

总结

由于let 避免了很多问题,所以建议在ES6的代码里总是使用let 来替代var.

扫码关注公众号,了解更多管理,见识,育儿等内容

作者: 王德水
出处:http://www.cnblogs.com/cnblogsfans
版权:本文版权归作者所有,转载需经作者同意。