ES6之"let"能替代"var"吗?
译者按: 使用let
的确会比var
安全很多。
原文: Why You Shouldn’t Use ‘var’ Anymore
译者: Fundebug
为了保证可读性,本文采用意译而非直译。
我已经使用ES2015(ES6)的语法编写JavaScript程序很久了,并且喜欢上它提供的新特性带来的优雅和简洁。我最习惯的就是不再使用var
,而是let/const
。我想当然的以为let
仅仅是var
的替代者,而事实上let
还为我们提供了更加精细的作用域。
我大多数时候使用的变量都是用const
来声明,因为如果尝试对使用const
声明的变量进行修改,将会报错。这可以避免不小心将一个不该修改的常量值修改。但是,我们还是需要可以声明可以被修改的变量,比如在循环里面的计数器,我们需要不断地对改变了加1。可是为什么我们使用let
而不是var
呢?
最简单的答案就是let
提供块作用域(block-scoping),这会比var
提供的以函数为作用域有更加精细化的控制。为了便于理解,我来用一个经典的前端工程师面试的问题来描述两者的区别。
问题: 在下面的例子中,请说出控制台的打印结果。
var callbacks = [];
(function() {
for (var i = 0; i < 5; i++) {
callbacks.push( function() { return i; } );
}
})();
console.log(callbacks.map( function(cb) { return cb(); } ));
|
我们将for循环执行五次,每次将一个函数push到callbacks
数组中。最后callbacks
数组里面的每一个函数的执行结果打印出来。
一个新手工程师经过深思熟虑可能会回答[0, 1 , 2, 3, 4]
, 然而却掉入了JavaScript
的”hoisting陷阱”。
只有当你理解了hoisting, 才能给出正确的答案[5, 5, 5, 5, 5]
。
var callbacks = [];
(function() {
var i;
for (i = 0; i < 5; i++) {
callbacks.push( function() { return i; } );
}
})();
console.log(callbacks.map( function(cb) { return cb(); } ));
|
注意上面的代码,JavaScript
将变量提升到函数定义的顶部,经过整个for
循环,callbacks
里面存储的5个函数指向的同一个变量i
的值已经是5。所以最终打印出来的值都为5。
在以前要通过各种奇淫技巧来解决这个问题,并成功返回[0, 1, 2, 3, 4]
, 现在我们有了let
,就可以很简单解决问题:
var callbacks = [];
(function() {
for (let i = 0; i < 5; i++) {
callbacks.push( function() { return i; } );
}
})();
console.log(callbacks.map( function(cb) { return cb(); } ));
|
因为let
拥有块作用域,所以使用let
声明的变量i
不会被提升到函数顶部,i
的作用域在for
循环, 就会每次循环有独立的值。
那我们是不是应该不要使用var
了呢?如果你想要一个变量拥有函数作用域,var
还是很有用的。
读者提到的两个问题:
const
声明的变量不是完全不可更改。比如:const myNotQuiteImmutableObject = {thisCanBeChanged: "not immutable"};myNotQuiteImmutableObject.thisCanBeChanged = "see I changed it.";但是,使用
const
声明可以阻止一些基本的更改,比如:const immutableString = "you can't change me";immutableString = "D'OH!"; // error如果你想要完全的不可更改,可以使用Facebook提供的Immutable库。
老版本的浏览器不支持
let
。不仅如此,而且有些最新的浏览器也还没有支持let
。我们可以使用Babel
来避免这个问题,Babel
允许你使用所有最新的JavaScript功能,然后将其翻译到甚至IE8都能支持的代码。
关于Fundebug
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了7亿+错误事件,得到了Google、360、金山软件、百姓网等众多知名用户的认可。欢迎免费试用!
版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/05/04/why-you-should-not-use-var/
ES6之"let"能替代"var"吗?的更多相关文章
- [ES6系列-04]再也不乱“哇”了:用 let 与 const 替代 var
[原创]码路工人 Coder-Power 大家好,这里是码路工人有力量,我是码路工人,你们是力量. github-pages 博客园cnblogs 今天的内容是,关于 JavaScript 中定义变量 ...
- ES6新增关键字let与var的区别
最近看了很多文章,偶然间看到ES6中新增了一个关键字 let ,它具有与 var 关键字相似的功能.一开始使用它时,发现它让我对之前一些习以为常的东西产生了怀疑. 下面先让我们看看它和 var 之间用 ...
- ES6 新增声明变量的 var let const 的区别详解
var 如果使用关键字 var 声明一个变量,那么这个变量就属于当前的函数作用域,如果声明是发生在任何函数外的顶层声明,那么这个变量就属于全局作用域. let 1.let 声明的变量具有块作用域的特征 ...
- li点击弹出序号
<body> <ul> <li>test1</li> <li>test2</li> <li>test3</li ...
- JavaScript 再谈闭包
之前有整理过一版关于闭包的概念,但感觉思路不是很清晰,是临时想起一些例子来讲的,今天再次来讲一下闭包. 闭包: 函数嵌套函数,内部函数可以引用外部函数的参数和变量 function aaa(a){ v ...
- 10个常见的JavaScript BUG
译者按: 安全起见,在开发中我基本不用==. 原文: 10 COMMON JAVASCRIPT BUGS AND HOW TO AVOID THEM 译者: Fundebug 为了保证可读性,本文采用 ...
- JavaScript中8个常见的陷阱
译者按: 漫漫编程路,总有一些坑让你泪流满面. 原文: Who said javascript was easy ? 译者: Fundebug 为了保证可读性,本文采用意译而非直译.另外,本文版权归原 ...
- JavaScript常用,继承,原生JavaScript实现classList
原文链接:http://caibaojian.com/8-javascript-attention.html 基于 Class 的组件最佳实践(Class Based Components) 基于 C ...
- 用纯JS实现,点击一个列表时,输出对应的索引(不能用JQuery哦)
你运行一下代码会发现,无论你点击哪个列表,控制台都是输出10.这是因为var声明的变量是函数作用域的,而不是块级作用域的.也就是说,for循环10次,每次都是改变同一个i,所以它的值会从0一直加到10 ...
随机推荐
- Spring-boot中使用@ConditionalOnExpression注解,在特定情况下初始化bean
想要实现的功能: 我想在配置文件中设置一个开关,enabled,在开关为true的时候才实例化bean,进行相关业务逻辑的操作. 具体实现: 1:要实例化的bean 2. 配置类 代码: 想要实例化的 ...
- sass 与 less 的区别与学习
一直使用的都是sass,公司提出新需求要用less,看了一下less的官方文档,感觉记不住.在这我想用与sass的比较学习,加深印象.也希望可以帮助到一些人. 一.安装sass与less sass基于 ...
- 利用Register protocol实现网页调用桌面程序(类似迅雷、QQ等)
前言 我们经常看到 tencent://.. thunder:// 这两种开头的网址,往往觉得很奇怪,很想弄懂其中的原理,是如何实现的,我查找了相关的 资料,终于找到了,跟大家分享下. 原理篇 ...
- border-radius IE8兼容处理
根据canisue(http://caniuse.com/#search=border-radius),border-radius兼容性如下图所示: 测试代码: <!DOCTYPE html&g ...
- 设计模式的征途—1.单例(Singleton)模式
单例模式属于创建型模式的一种,创建型模式是一类最常用的设计模式,在软件开发中应用非常广泛.创建型模式将对象的创建和使用分离,在使用对象时无需关心对象的创建细节,从而降低系统的耦合度,让设计方案更易于修 ...
- Spring MVC 处理异常的3种方式
使用Spring MVC开发的博客网站时,遇到了如何处理业务层抛出的异常的问题,查阅到了spring官方博客-spring MVC中异常的处理,以下将会以登录模块为示例. 愚蠢的处理方式 处理异常遵循 ...
- Zookeeper-3.4.9 集群搭建
这里用了三台主机,系统为CentOS7 1.修改hosts #vim /etc/hosts 172.50.0.31 node1 172.50.0.34 node2 172.50.0.37 node3 ...
- Git安装与上传代码至Github
转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6642887.html 这篇文章应该是全网最新,最全,最靠谱的Github安装到上传代码的流程. 1.Git ...
- XML文档结构
<?xml version="1.0" encoding="UTF-8"?> <books> <bool id="bk1 ...
- C# 遍历泛型集合
/// <summary> /// 遍历泛型 /// </summary> /// <typeparam name="T"></typep ...