ES6做为新一代JavaScript标准,已正式与广大前端开发者见面。为了让你们对ES6的诸多新特性有更深刻的了解,Mozilla Web开发者博客推出了《ES6 In Depth》系列文章。CSDN已获受权,将持续对该系列进行翻译,组织成【探秘ES6】系列专栏,供你们学习借鉴。本文为该系列的第十二篇。
前端
本文介绍的是有关let和const关键字的使用。 node
对于JS而言,开发者有可能遇到如下两个问题。 es6
问题一:区块不等同于做用域。 web
在一个JS函数中声明的变量的做用域是在整个函数里,由此将会引起两个问题。 函数
第一个是区块里定义的变量的做用域不只限于区块,而是做用于整个函数中。请看如下例子,里面定义的变量是t: 工具
function runTowerExperiment(tower, startTime) { var t = startTime; tower.on("tick", function () { ... code that uses t ... }); ... more code ... }
若是要增长一个用于检测保龄球速度的功能,可能会这样写: 学习
function runTowerExperiment(tower, startTime) { var t = startTime; tower.on("tick", function () { ... code that uses t ... if (bowlingBall.altitude() <= 0) { var t = readTachymeter(); ... } }); ... more code ... }
如今问题来了,咱们不自觉地添加了一个同名变量 t ;而这个 t 的做用域会发生改变,再也不是第一次定义时的t了。可见,JS中的变量相似于Photoshop中的油漆桶工具,至声明开始能够向前或向后做用直到碰到函数边界,咱们称之为“抬升”。这个例子中抬升致使的结果是,以 t 为计算对象的结果会产生NaN。 编码
问题二:变量在循环体中的共享 spa
请先看下面: .net
var messages = ["Hi!", "I'm a web page!", "alert() is fun!"]; for (var i = 0; i < messages.length; i++) { alert(messages[i]); }
这段代码的运算结果是显而易见的,可是若是换成下面这种方式呢?
var messages = ["Meow!", "I'm a talking cat!", "Callbacks are fun!"]; for (var i = 0; i < messages.length; i++) { setTimeout(function () { cat.say(messages[i]); }, i * 1500); }
其结果会是怎么样?详见 完整示例
结果是连续三个undefined?!缘由就是变量的共享问题。仅有的变量 i 被循环体以及全部timeout回调共享了,其结果就是当循环结束时i=3,因此使用messages[3]做为输出会显示undefined,由于没有定义这个元素。若是要解决这个问题,有好几种方法,详见 连接 。
使用let代替var
为了解决向后兼容的编码问题,Brendan Eich引入了关键字let。当你要进行全局搜索的时候,若是以前使用var来定义变量,那么会致使编码不能连续。因此在ES6里,请尝试使用let而不是var。
这二者的主要区别是:
let变量是区域变量:let定义的变量仅限于局部区块内,而不是整个函数体内。因此使用let就可避免前述的变量共享问题。
全局let变量不是全局对象的属性:也就是说,你不能使用window.variableName的方式来使用它们。相反,它们的活动范围是在于Web页面下的非可视JS代码区块内。
for(let x…)形式的循环在遍历时会产生新的x:这是一个很美妙的地方。它是意思是若是一个for (let...)循环中包含结束,例如前述的talking cat例子,那么每一个结束会获得不一样的变量输出,而不是都使用相同的变量。因此也就解决了变量共享的问题。此外,该特性对for-of,for-in都是适用的。
在使用let声明变量前使用变量会出错:例如这些编写的话,将会出现引用错误:
function update() { console.log("current time:", t); // ReferenceError ... let t = readTachymeter(); }
重复使用let声明变量会致使语法错误。
该约束是能帮忙检查出一些粗枝大叶的问题。
使用const
相似于其它语言,ES6中可以使用const进行常量定义;若是尝试对已经定义的常量进行赋值,将会引发语法错误:
const MAX_CAT_SIZE_KG = 3000; // MAX_CAT_SIZE_KG = 5000; // SyntaxError MAX_CAT_SIZE_KG++; // nice try, but still a SyntaxError
一样地,定义的同时不对常量赋值也是一个语法错误:
const theFairest; // SyntaxError, you troublemaker
如何启用let和const?
请使用ES6编译器,例如Babel,Traceur或者TypeScript。io.js可在strict模式下使用;node.js与之相似,可是须要启用harmony选项。
原文连接:ES6 In Depth: let and const
(译者:伍昆,责编:陈秋歌)
本译文遵循Creative Commons Attribution Share-Alike License v3.0