ES6深入理解之“let”能替代”var“吗?


Posted in Javascript onJune 28, 2017

前言

我已经使用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还是很有用的。

读者提到的两个问题:

1、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库。

2、老版本的浏览器不支持let。不仅如此,而且有些最新的浏览器也还没有支持let。我们可以使用Babel来避免这个问题,Babel允许你使用所有最新的JavaScript功能,然后将其翻译到甚至IE8都能支持的代码。

原文: Why You Shouldn't Use ‘var' Anymore

译者: Fundebug

为了保证可读性,本文采用意译而非直译。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
javascript实现锁定网页、密码解锁效果(类似系统屏幕保护效果)
Aug 15 Javascript
jQuery插件slider实现拖动滑块选取价格范围
Apr 30 Javascript
javascript动态获取登录时间和在线时长
Feb 25 Javascript
jquery遍历table的tr获取td的值实现方法
May 19 Javascript
将鼠标焦点定位到文本框最后(代码分享)
Jan 11 Javascript
Angular指令之restict匹配模式的详解
Jul 27 Javascript
Vue基于NUXT的SSR详解
Oct 24 Javascript
Spring boot 和Vue开发中CORS跨域问题解决
Sep 05 Javascript
JavaScript常用数组操作方法,包含ES6方法
May 10 Javascript
记一次vue去除#问题处理经过小结
Jan 24 Javascript
判断文字超过2行添加展开按钮,未超过则不显示,溢出部分显示省略号
Apr 28 Javascript
解决layer 动态加载select 失效的问题
Sep 18 Javascript
jQuery、layer实现弹出层的打开、关闭功能
Jun 28 #jQuery
AngularJS实现单一页面内设置跳转路由的方法
Jun 28 #Javascript
JavaScript中常见的八个陷阱总结
Jun 28 #Javascript
通过构造函数实例化对象的方法
Jun 28 #Javascript
JS之if语句对接事件动作逻辑(详解)
Jun 28 #Javascript
CSS3+JavaScript实现翻页幻灯片效果
Jun 28 #Javascript
Node.js 8 中的重要新特性
Jun 28 #Javascript
You might like
骨王战斗力在公会成员中排不进前五,却当选了会长,原因竟是这样
2020/03/02 日漫
php实现图片添加描边字和马赛克的方法
2014/12/10 PHP
PHP实现批量清空删除指定文件夹所有内容的方法
2017/05/30 PHP
用javascript实现的仿Flash广告图片轮换效果
2007/04/24 Javascript
8款非常棒的响应式jQuery 幻灯片插件推荐
2012/02/02 Javascript
javascript打开word文档的方法
2014/04/16 Javascript
jQuery针对各类元素操作基础教程
2014/08/29 Javascript
javascript 实现 原路返回
2015/01/21 Javascript
JavaScript实现简单的拖动效果
2016/07/02 Javascript
使用jQuery5分钟快速搞定双色表格的简单实例
2016/08/08 Javascript
AngularJS中关于ng-class指令的几种实现方式详解
2016/09/17 Javascript
Html中 IFrame的用法及注意点
2016/12/22 Javascript
JavaScript实现审核流程状态的动态显示进度条
2017/03/15 Javascript
详解使用mpvue开发github小程序总结
2018/07/25 Javascript
vue组件内部引入外部js文件的方法
2020/01/18 Javascript
[41:52]2018DOTA2亚洲邀请赛3月29日小组赛B组Effect VS Secret
2018/03/30 DOTA
用python删除java文件头上版权信息的方法
2014/07/31 Python
python timestamp和datetime之间转换详解
2017/12/11 Python
python命令行解析之parse_known_args()函数和parse_args()使用区别介绍
2018/01/24 Python
Python中的相关分析correlation analysis的实现
2019/08/29 Python
tensorflow实现对张量数据的切片操作方式
2020/01/19 Python
Python操作Excel工作簿的示例代码(\*.xlsx)
2020/03/23 Python
关于jupyter打开之后不能直接跳转到浏览器的解决方式
2020/04/13 Python
python 使用事件对象asyncio.Event来同步协程的操作
2020/05/04 Python
python爬虫中的url下载器用法详解
2020/11/30 Python
美国网上鞋子零售商:Dr. Scholl’s Shoes
2017/11/17 全球购物
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
经济实惠的名牌太阳镜和眼镜:Privé Revaux
2021/02/07 全球购物
自我鉴定写作要点
2014/01/17 职场文书
办公室主任职责范本
2014/03/07 职场文书
公司联欢晚会主持词
2014/03/22 职场文书
班长演讲稿范文
2014/04/24 职场文书
法定代表人资格证明书
2014/09/11 职场文书
委托书的写法
2014/09/16 职场文书
pytorch锁死在dataloader(训练时卡死)
2021/05/28 Python
windows安装 redis 6.2.6最新步骤详解
2022/04/26 Redis