【探秘ES6】系列专栏(十二):let和const

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 

相关文章
相关标签/搜索