Vue 开发中可以使用的 ES6 新特征
ECMAScript 6.0(以下简称 ES6)是 Javascript 语言的下一代标准,正式发布与 2015 年 6 月。它的目标,是使得 Javascript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
ECMAScript 6,即所谓的现代 Javascript,具有强大的功能,例如块作用域、类、箭头功、生成器以及许多其他有用的功能。
在 Vue 应用开发中使用的所有必要功能来改善编程体验,提高开发效率及代码质量。通过Vue CLI
的Babel
或core-js
集成,使开发中的代码严格按照配置规范进行迭代,有助于团队协作。
let/const
ES6 最基本的功能:let
和const
。
let
与var
类似,但使用let
声明的变量的作用域是在声明它们的块中。(Block 指条件块,for
循环块等)
例如,在条件块中使用let
将在块内作用域变量,在块外不可用。
在这里,错误是一件好事,因为它可以防止在生产过程中发生潜在的错误。
如果在上面的例子中使用var
(就像在传统的 Javascript 代码中那样)而不是let
,就不会出现错误。
const
是另一个用于声明变量的 ES6 关键字。不同之处在于const
创建的变量在声明之后不能更改,这个特点可以有效的避免 BUG 的出现,因此在编写代码过程中,建议尽量写纯函数(纯函数,就是给定函数固定的输入,输出的结果就是固定的,不会受函数外的变量等的影响)。
例如:
有几种创建变量的方法,我们应该使用哪一种?
最好的做法是尽可能使用const
。只有当你需要一个以后需要更改的变量时才使用let
,比如在for
循环中。
for…of
说到循环,在 ES6 语法中有一种更简单的方法来编写for
循环,甚至不需要使用let
。
例如,一个传统的for
循环是这样的:
在 ES6 中,非常简单:
不要与for..in
语法混淆;他们是完全不同的东西。 for..in
将获得数组/对象中的属性,而for..of
将获得实际想要迭代的数据。
Iterable
可迭代对象是实现可迭代协议的任何对象。(协议只是指需要通过在对象中使用特定名称的特定方法来满足的需求。)
例如,下面是一个实现了iterable
协议的对象:
现在可以在for..of
循环中使用此twice
对象:
这会对twice
对象进行两次循环,分别得到 0 和 1。
为了创建一个可迭代对象,实际上实现了两个协议,iterable
协议和iterator
协议。
为了满足作为可迭代对象的要求,需要一个名为[Symbol.iterator]
的方法。
方法名中应用了两个新的 ES6 技巧。
首先,Symbol.iterator
一个内置的符号值,而Symbol
是 ES6 中用于创建唯一标签/标识符的基本类型。
其次,包装属性键的方括号使它成为一个动态计算的键。这里的关键是表达式符号。迭代器将被求值为,通常不关心实际的求值是什么。这个不重要的细节被抽象掉了。
这就是可迭代的协议。现在仍然需要处理迭代器协议来创建可迭代的对象,因为必须从 [Symbol.iterator]
函数返回一个迭代器,迭代器协议更简单。只需要一个对象有一个next
方法即可返回带有两个键的对象:value
和done
。当要停止迭代时,只需返回对象{value:undefined,done:true}
。
这是示例中的迭代器:
总之,有一个同时满足可迭代协议和迭代器协议的对象。如以下代码:
数组和字符串可以使用
for..of
,进行迭代。这意味着这些内置类型包含与上面的类似的[Symbol.iterator]
方法。
Generator:生成器
与迭代相关的另一个功能是生成器。
上面的可迭代代码依靠闭包来存储 i
变量。使用 generator
时,不必担心自己构造闭包:
该代码实现了与可迭代示例相同的行为,但更为简单。
可以与for..of
完全相同地使用它:
如你所见,它是一个带有星号(*
)声明的函数。它使用yield
关键字逐个抽取值,就像迭代器的next
方法一样。
生成器是一种多功能工具,基本上,它是一种允许暂停/恢复功能的机制。不必在for..of
中使用上述twice
对象。可以调用它的next
方法。
此时,twiceGen
函数在第一次运行while
循环后暂停。如果再次运行相同的操作,它将恢复并播放循环的第二次运行。
生成器的妙处在于它还创建了一个可迭代的迭代器对象。这就是为什么我们能够使用for..of
(可迭代特权)迭代两次并直接调用其next
方法(迭代器特权)的原因。
Default Parameter:默认参数
可能不会立即创建自己的迭代器、生成器,所以让我们来看看其他一些 ES6 的独创性,它们可以立即使你的代码更加友好。
就像许多其他编程语言一样,现在可以为函数参数设置默认值。
过去是这样实现默认值的:
现在可以这样:
Destructuring Syntax:解构语法
解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。
如果要将对象传递给函数,则可以轻松选择对象的属性,然后使用 ES6 分解语法将它们放在单独的变量中:
这种解构语法的好处是可以避免创建带有附加代码行的变量。因此不需要像下面这样:
同样,还可以在解构语法中设置默认值:
解构语法也适用于赋值:
当从参数以外的地方获取对象时,这也很有用。
解构技巧同样也适用数组。
解构参数:
解构赋值:
Rest / Spread :剩余 / 展开参数
在解构数组时,可以使用 ...
语法来获取数组中的所有其他项。
c
现在是一个包含自己的数组,包含了其余的元素:3
,4
,5
。这里的操作就是Rest
操作。
这个语法同样适用于赋值:
rest
操作符也可以单独使用,无需解构:
在这里,我们将数字作为独立参数传递,而不是作为单个数组传递。但是在函数内部,使用rest
运算符将数字作为单个数组收集。当遍历这些参数时,这很有用。
rest 语法 ...
与另一个 ES6 特性操作符扩展完全相同。
例如,如果要将两个数组合并为一个:
spread
操作符用于将所有项展开,并将它们放入不同的数组中。
spread
也适用于对象:
现在,第二个对象除了其自身的属性外,还应包含第一个对象的所有内容。
Arrow Function:箭头函数
ES6 提供了创建函数,对象和类的更简单方法。
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this
,arguments
,super
或new.target
。
箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
使用箭头语法来创建更简洁的函数:
箭头语法对于创建单行函数更加简洁友好。
此函数将自动返回表达式num +1
的求值作为返回值,不需要显式的使用return
关键字。
如果函数仅接受一个参数,甚至可以省略括号(但是在严格语法上还是建议加上括号):
但是如果没有任何参数,仍然需要一对空括号:
但是,此语法有一个警告,如果我们返回的是对象字面量,则无法使用,会报错:
这将产生语法错误,因为解析器将假定花括号用于函数块,而不是对象字面量。
为了避免这个错误,必须将对象字面量包装在一对括号中:
另一件需要记住的事情是,this
关键字不能在箭头函数中使用。它不会出现错误;相反,它只会从周围的范围提供相同的this
引用。
以上代码给出的值则为:true
Object literal extensions:对象字面量的扩展
ES6 也提供了一种更简单的方法来创建对象字面量。
如果在一个对象中放入两个项目,它们的属性键与变量相同,可以用传统的 Javascript 做这样的事情:
但是在 ES6 中,语法可以更简单:
如果把方法放到对象字面量中,可以这样做:
>基本上,没有function
关键字和冒号。
Class:类
ES6 提供了类似于其他面向对象语言的类构造。现在不必依赖于混淆构造函数和原型方式。
附带说明,introduce
方法中的字符串称为模板字符串,它是使用反引号而不是引号创建的。这样可以使用美元符号和大括号将表达式插入字符串。
与常规字符串拼接相比,模板字符串的好处是它可以跨越多行:
它被称为模板字符串,因为它对实现模板很有用。
一个类可以从另一个类继承(重用现有类的代码):
这里使用extends
关键字在两个类之间创建继承关系,其中Person
为父类。代码中用了两次super
关键字,第一次是在构造函数中调用父类的构造函数,第二次,像使用对象一样使用它来调用父类的introduce
方法。super
关键字的行为会因使用的位置而异。
在构造函数中使用时,
super
关键字将单独出现,并且必须在使用this
关键字之前使用。如下代码就是有异常的。
Map / Set / WeakMap / WeakSet
ES6 新增了两种数据结构:Map
和Set
Map
是键-值
对的集合,并且能够记住键的原始插入顺序。
Map
对象可以使用任何对象类型作为键。看起来是不有点像 Object,下面我们可以看看他们的比较:
Set
对象就像一个数组,但是仅包含唯一项。Set
对象是值的集合,可以按照插入的顺序迭代它的元素。 Set
中的元素只会出现一次,即 Set
中的元素是唯一的。
尽管两次add
是同样的值,程序本身不会出现任何异常,但该集合仍然只包含一项。
让谈谈来学习一点更复杂的知识,WeakMap
和WeakSet
。它们分别是Map
和Set
的弱引用版本。
WeakMap
其键必须是Object
,而值可以是任意的。
WeakSet
对象是一些对象值的集合, 并且其中的每个对象值都只能出现一次,在WeakSet
的集合中是唯一的。
它和 Set
对象的区别有两点:
与
Set
相比,WeakSet
只能是对象的集合,而不能是任何类型的任意值。WeakSet
持弱引用:集合中对象的引用为弱引用。 如果没有其他的对WeakSet
中对象的引用,那么这些对象会被当成垃圾回收掉。 这也意味着WeakSet
中没有存储当前对象的列表。 正因为这样,WeakSet
是不可枚举的。
一旦不再引用WeakMap
的键,便会对其进行垃圾回收(由 Javascript 运行时从内存中删除)。
在key1
被取消引用之后,它的对应值将被垃圾回收,意味着它将在未来的某个时间点消失。
同样,如果将一个对象添加到WeakSet
中,然后再取消引用它,它也将被垃圾回收。
Promise
Promise
对象用于表示一个异步操作的最终完成 (或失败)及其结果值。是 ES6 的一个常用功能,它是对传统函数回调模式的改进。
一个 Promise 必然处于以下几种状态之一:
待定(
pending
): 初始状态,既没有被兑现,也没有被拒绝。已兑现(
fulfilled
): 意味着操作成功完成。已拒绝(
rejected
): 意味着操作失败。
例如,这是使用传统回调的方式:
这是一个计时器,显示一秒钟后的时间。
这是一个使用相同setTimeout
逻辑的Promise
对象:
它接受带有两个参数的函数:resolve
和reject
。这两个都是当有返回值时可以调用的函数。调用resolve
函数返回一个值,可以调用reject
函数返回一个错误。
然后,可以使用then
语法将回调函数附加到这个afteronessecond
对象上:
promise
相对于传统回调的好处是promise
对象可以被传递。因此,在设置promise
之后,可以自由地将它发送到其他地方,以处理计时器解析后要做的事情。
另一个很酷的事情是,promise 可以与多个 then 子句链接在一起,即promise
的链式调用。
每个
then
子句将其值作为参数返回到下一个then
子句。
实用方法
下面就来介绍在 VUE 中,比较实用的 ES6 的方法或属性。
Object.assign()
Object.assign()
方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。提供了一种简单的方法来浅克隆现有对象。
String.prototype.repeat()
构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。
String.prototype.startsWith()
用来判断当前字符串是否以另外一个给定的子字符串开头(区分大小写),并根据判断结果返回
true
或false
。
String.prototype.endsWith()
用来判断当前字符串是否是以另外一个给定的子字符串“结尾”的,根据判断结果返回
true
或false
。
String.prototype.includes()
用于判断一个字符串是否包含在另一个字符串中,根据情况返回
true
或false
。
Array.prototype.find()
返回数组中满足提供的过滤函数的第一个元素的值,否则返回
undefined
。
Function.name
这不是方法而是属性,返回函数实例的名称,每个函数都有一个
name
属性,该属性提供字符串形式的函数名称
总结
ES6 的新特征,某种程度上代表的 Javascript 在未来的态度,这些新的特征让我迫不及待应用到项目中,不断接受新挑战,提升自己技能。
版权声明: 本文为 InfoQ 作者【devpoint】的原创文章。
原文链接:【http://xie.infoq.cn/article/390e7c5dc336f3f5b1db9c78d】。文章转载请联系作者。
评论