05月23, 2016

【译】在 ES6 中 改良的 5 个 JavaScript “缺陷”

原文:http://www.zcfy.cc/article/315

ECMAScript 6 (ES6) 新特性可以分为新增语法(例如:class),增强 JavaScript 功能(例如:import),以及改良 JS “缺陷” (例如:let 关键字)。大部分博客将这三类新特性混在一起介绍,往往让 ES6 新手晕菜。因此我决定写下这篇文章仅仅介绍改良 JS “缺陷”的这部分特性。

我希望通过这篇文章介绍,能让你明白只要使用一小部分 ES6 新特新,例如 let、箭头函数等,你就能获得巨大的回报。

好,让我们开始吧。

1. 块级作用域

ES5 只有函数作用域(例如,我们必须将代码包在函数内来限制作用域),这导致很多问题。ES6 提供 letconst 来代替 var 声明变量,新的声明方式支持用大括号表示的块级作用域。

防止变量在作用域外被访问

下图展示了 if 语句内声明的“bonus”变量在使用 let 的时候被限制在 if 的作用域内,这样不会影响到作用域外面的同名变量,这也是与大部分其他编程语言一致的行为。

点击图片查看大图

防止重复声明变量

ES6 不允许在同一个作用域内用 letconst 重复声明同名变量。这对于防止在不同的 js 库中存在重复声明的函数表达式十分有帮助。

例如下图的 add 函数:

点击图片查看大图

不再需要立即执行的函数表达式(IIFE)

在 ES5 中,像下图中的例子,我们需要构造一个立即执行的函数表达式去保证我们不污染全局作用域。在 ES6, 我们可以使用更简单的大括号({}),然后使用 const 或者 let 代替 var 来达到同样的效果。

点击图片查看大图

Babel - 一个转换 ES6 代码为 ES5 代码的工具

我们的 ES6 代码最终要运行在浏览器里。Babel 是最流行的将 ES6 转为 ES5 的工具。它拥有许多使用方式,例如命令行、node 模块以及在线编译。我在我的应用中使用 node 模块编译代码,使用在线编译来快速查看 ES6 代码对应的 ES5 版本的区别。

下图演示了 Babel 如何通过重命名变量来模拟 “let” 和 “const”

点击图片查看大图

循环体中的闭包不再有问题

在 ES5 中,如果循环体内有产生一个闭包,访问闭包外的变量,会产生问题。在 ES6 中,你可以使用 “let” 来避免问题。

点击图片查看大图

注意: 在这里你不能用 const ,因为 i 在变, 不过你可以在新的 for...of 循环中使用 const

2. 词法作用域的 “this” (通过箭头函数)

在 ES5 中,“this” 会随着函数调用位置和调用方式改变,这种变化无常给很多开发者带来过痛苦的经历。 ES6 通过箭头函数带来的词法作用域的 “this” 消除了这个问题。

词法作用域的 “this” 特性让变量的 “this” 总是指向词法声明时的那个对象。

“this” 问题和 ES5 中的两个解决方法:

在下图中,我们希望打印一个用户的名字和薪水。假设我们从服务器异步获取薪水数据。注意到当服务器返回结果时,函数里的 “this” 是 “window” 而不是 “person”。

点击图片查看大图

ES5 中的 “this” 问题和两种解决方式

在 ES6 中的解决方法:

在 ES6 中简单使用箭头函数就可以自动获得词法作用域的 “this”

点击图片查看大图

第16行代码演示了如何使用箭头函数

下图演示了 Babel 如何将箭头函数转为普通的 ES5 函数:

点击图片查看大图

3. 处理 “arguments”

在 ES5 中,“arguments” 表现得像一个数组(例如:我们可以通过length来遍历它),但是它不是一个真正的数组。所以,一切数组方法,比如 sort、slice 等等都用不了。

在 ES6 中,我们可以使用一个新的特性叫做 rest 参数。它的形式为...参数名(比如:...args)。rest 参数是一个真正的数组,所以我们可以对它使用所有数组上可用的方法。

下图演示 rest 参数的用法:

点击图片查看大图

4. 类

从概念上讲,在 ES6 之前的 JS 中并没有和其他面向对象语言那样的“类”的概念。长时间里,人们把使用 new 关键字通过函数(也叫构造器)构造对象当做“类”来使用。

由于 JS 不支持原生的类,而只是通过原型来模拟,各种模拟类的方式相对于传统的面向对象方式来说非常混乱,尤其是处理当子类继承父类、子类要调用父类的方法等等需求时

ES6 带来了新的语法,与其他各种编程语言类似的语法,使得面向对象变得非常简单。

下图对比在 ES5 和 ES6 中实现类:

点击图片查看大图

ES5 Vs ES6 (es6-features.org)

更新:在阅读了本文之后一定要读:《Is “Class” In ES6 The New “Bad” Part?》

5. 严格模式

严格模式(use strict) 有助于防止问题用法,并且它也有助于安全使用 JavaScript。在 ES5 中, 严格模式是可选项,但是在 ES6 中,许多特性要求必须使用严格模式。 因此大多数开发者和 babel 之类的工具默认添加 use strict 到 JS 文件的头部,以确保整个 JS 文件的代码都采用严格模式,这个习惯有助于我们书写更好的 JavaScript。

英文原文:https://medium.com/@rajaraodv/5-javascript-bad-parts-that-are-fixed-in-es6-c7c45d44fd81#.et5iocmgc

本文链接:https://www.h5jun.com/post/5-javascript-“bad”-parts-that-are-fixed-in-es6.html

-- EOF --

Comments