您是否知道JavaScript(以及JScript和ActionScript)是称为ECMAScript的通用客户端脚本语言规范的实现? 为了使这个令人讨厌的定义更具吸引力,我们可以说ECMAScript(或正式的ECMA-262 )是定义我们如何使用JavaScript以及如何使用JavaScript的标准 。
该语言的最新第六版ECMAScript 2015(或ES6)可能是自1997年第一版以来最重要的更新。最新版本的主要目标是为创建更大的应用程序和库提供更好的支持。 这意味着更成熟的语法,使编码更容易的新快捷方式,以及新的方法,关键字,数据类型和许多其他增强功能。
ES6文档内容丰富,如果您想阅读很多,可以从ECMA International网站下载整个规范 。 在本文中,我们将介绍10种精选功能,即使ES6可以提供更多功能。 如果您想尝试一下, ES6 Fiddle是一个不错的选择,并且您还可以在此处找到一些示例代码片段。
![ES6 ES6小提琴](https://i-blog.csdnimg.cn/blog_migrate/eaefe73c4d44c2acc17fc8fe7ef8e785.png)
支持ECMAScript 6
浏览器供应商已逐渐增加了对ECMAScript 6功能的支持。您可以在此处找到一个很酷的兼容性表,其中涉及浏览器和编译器对新功能的支持。
如果您对Node.js中的ES6支持感兴趣,请在此处查看文档。
虽然不是所有的功能,目前支持,我们可以使用transpilers如巴贝尔以transpile我们ES6代码ES5。 有一个很酷的Babel Grunt插件 ,许多很棒的Grunt ES6插件以及一个了不起的Gulp-Babel插件 ,所以幸运的是我们有很多选择。
这样,我们就可以开始使用增强的语法和功能,而不必担心兼容性问题。 现在让我们看一下功能。
![ES6兼容性表](https://i-blog.csdnimg.cn/blog_migrate/67afca07b82921d5f875cd24a49f5707.png)
1.新的
ES6引入了新的let
关键字,该关键字允许我们在块的范围内声明局部变量,例如语句,表达式或(内部)函数。 例如,我们可以通过以下方式声明一个for
循环,然后在下一个if
语句内重用相同的变量名(因为其范围仅限于for
循环):
for (let i = 0; i < myArray.length; i++) {
// Do something inside the block
}
if (x > 0 && x != y) {
// We reuse "i"
let i = x * y
}
使用let
关键字可以使代码更简洁,更可用。 let
和var
之间的区别在于范围,例如,可以在整个封闭函数中使用由var
关键字定义的局部变量,而由let
定义的变量只能在它们自己的(子)块中使用。 Let
也可以全局使用,在这种情况下,它的行为与var
相同。 当然,如果需要,在ES6中我们仍然可以使用var
。
2.新的
新的const关键字使声明常量(也称为不可变变量)成为可能,我们以后无法向其重新分配新内容。
const MY_CONST = 12;
console.log(MY_CONST);
// 12
MY_CONST = 16;
// Silent error, as we cannot reassign a new value to a constant
不可变变量在ECMAScript 6中并不总是完全不可变的,就好像常量持有一个对象一样,我们以后可以更改其属性和方法的值。 对于数组的元素也是如此。
const MY_CONSTANT = {myProperty: 6};
console.log(MY_CONSTANT.myProperty);
// 6
MY_CONSTANT.myProperty = 18;
console.log(MY_CONSTANT.myProperty);
// 18
const OTHER_CONSTANT = [12, 14, 16];
console.log(OTHER_CONSTANT[0]);
// 12
OTHER_CONSTANT[0] = 22;
console.log(OTHER_CONSTANT[0]);
// 22
在上述代码段中,我们仍然无法直接将新值重新分配给MY_CONSTANT对象,这意味着我们无法更改属性和方法的名称,也无法添加新值或删除现有的值,因此我们无法执行以下内容:
MY_CONSTANT = {newProperty: 18};
console.log(MY_CONSTANT.newProperty);
// error
3.箭头功能
ECMAScript 6简化了我们编写匿名函数的方式 ,因为我们可以完全省略function
关键字。 我们只需要对箭头函数使用新的语法,以=>箭头符号(胖箭头)命名,这为我们提供了一个捷径。
// 1. One parameter in ES6
let sum = (a, b) => a + b;
// in ES5
var sum = function(a, b) {
return a + b;
};
// 2. Without parameters in ES6
let randomNum = () => Math.random();
// in ES5
var randomNum = function() {
return Math.random();
};
// 3. Without return in ES6
let message = (name) => alert("Hi " + name + "!");
// in ES5
var message = function(yourName) {
alert("Hi " + yourName + "!");
};
常规函数和箭头函数之间有一个重要区别,即箭头函数不会像使用function
关键字do定义的function
那样自动接收this
值。 箭头函数以词法 this
值绑定到当前作用域。 这意味着我们可以轻松地在内部函数中重用this
关键字。 在ES5中,只有以下情况才有可能:
// ES5 Hack to use the "this" keyword in an inner function
{
...
addAll: function addAll(pieces) {
var self = this;
_.each(pieces, function (piece) {
self.add(piece);
});
},
...
}
// ES6 the same inner function now can use its own "this"
{
...
addAll: function addAll(pieces) {
_.each(pieces, piece => this.add(piece));
},
...
}
4.新的点
新的点spread
运算符标记有3个点(…),我们可以使用它来标记多个预期项目的位置。 散布运算符最常见的用例之一是将一个数组的元素插入另一个数组:
let myArray = [1, 2, 3];
let newArray = [...myArray, 4, 5, 6];
console.log(newArray);
// 1, 2, 3, 4, 5, 6
我们还可以在要从数组中传递参数的函数调用中利用spread
运算符:
let myArray = [1, 2, 3];
function sum(a, b, c) {
return a + b + c;
}
console.log(sum(...myArray));
// 6
5.参数和新其余参数的默认值
好消息,在ECMAScript 6中,我们可以将默认值添加到函数的参数中。 这意味着,如果我们稍后在函数调用中不传递参数,则将使用默认参数。 在ES5中,参数的默认值始终设置为undefined
,因此将其设置为所需参数的新可能性无疑是对语言的极大增强。
function sum(a = 2, b = 4) {
return a + b;
}
console.log( sum() );
// 6
console.log( sum(3, 6) );
// 9
ES6还引入了一种新的参数, 其余参数 。 它们的外观和工作方式与分散运营商相似。 如果我们不知道稍后在函数调用中传递多少个参数,它们将很方便。 我们可以在其余参数上使用Array对象的属性和方法:
function putInAlphabet(...args) {
let sorted = args.sort();
return sorted;
}
console.log( putInAlphabet("e","c","m","a","s","c","r","i","p","t") );
// a,c,c,e,i,m,p,r,s,t
6.声明的新
借助新的for...of
循环,我们可以轻松地遍历数组或其他可迭代对象。 除了新的for...of
语句外,ECMAScript 6还引入了两个新的可迭代对象,即Map(用于键/值映射)和Set(用于唯一值的集合),这些值也可以是原始值和对象引用。 当我们使用for...of
语句时,将对可迭代对象的每个元素执行块内的代码。
let myArray = [1, 2, 3, 4, 5];
let sum = 0;
for (let i of myArray) {
sum += i;
}
console.log(sum);
// 15 (= 1 + 2 + 3 + 4 + 5)
7.模板文字
ECMAScript 6为我们提供了一个新的字符串连接替代方案。 模板文字使我们能够轻松创建模板,在其中可以将不同的值嵌入到所需的任何位置。 为此,我们需要在要插入可通过以下方式从变量,数组或对象传递的数据的任何地方使用${...}
语法:
let customer = { title: 'Ms', firstname: 'Jane', surname: 'Doe', age: '34' };
let template = `Dear ${customer.title} ${customer.firstname} ${customer.surname}!
Happy ${customer.age}th birthday!`;
console.log(template);
// Dear Ms Jane Doe! Happy 34th birthday!
8.班级
ES6引入了基于现有基于原型的继承构建JavaScript类。 新语法使创建对象,利用继承和重用代码更加直接。 这也将使来自其他编程语言的初学者更容易理解JavaScript的工作原理。
在ES6中,类是使用new class
关键字声明的,并且需要具有当使用new myClass()
语法实例化新对象时调用的constructor()
方法。 也可以使用class Child extends Parent
语法class Child extends Parent
扩展新类,而其他面向对象的语言(例如PHP)可能熟悉这种语法。 同样重要的是要知道,与函数和变量声明不同,ECMAScript 6中没有悬挂类声明。
class Polygon {
constructor(height, width) { //class constructor
this.name = 'Polygon';
this.height = height;
this.width = width;
}
sayName() { //class method
console.log('Hi, I am a', this.name + '.');
}
}
let myPolygon = new Polygon(5, 6);
console.log(myPolygon.sayName());
// Hi, I am a Polygon.
上面来自ES6 Fiddle示例的代码,。
9.模块
您是否曾经想过,如果JavaScript是模块化的,那会有多酷? 当然,之前有解决方法,例如CommonJS (用于Node.js )或AMD(异步模块定义) (用于RequireJS ),但是ES6引入了模块作为本机功能。
我们需要在其自己的文件中定义每个模块,然后根据以下语法,使用export
关键字将变量和函数导出到其他文件,并使用import
关键字从其他文件导入它们:
// functions.js
function cube(a) {
return a * a * a;
}
function cubeRoot(a) {
return Math.cbrt(a);
}
export { cube, cubeRoot}
// or: export { cube as cb, cubeRoot as cr }
// app.js
import { cube, cubeRoot } from 'functions';
console.log(cube(4));
// 64
console.log(cubeRoot(125));
// 5
该解决方案非常出色,因为从外部看不到存储在模块中的代码,并且我们只需要导出要被其他文件访问的部分。 我们可以使用ES6模块做更多令人惊奇的事情, 在这里您可以找到有关它们的详细解释。
10.新方法的负担
ECMAScript 6为现有的字符串原型,数组对象,数组原型和数学对象引入了许多新方法。 新方法可以显着改善我们操纵这些实体的方式。 Mozilla Dev拥有很好的新代码示例 ,值得花一些时间来仔细研究它们。
为了展示它们的真实性,这是我的最爱:Array原型的find方法,它使我们能够通过对每个元素执行回调函数,然后返回第一个元素来测试数组元素上的某些条件。返回true
。
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) {
return false;
}
}
return element > 1;
}
console.log([4, 6, 8, 12].find(isPrime));
// undefined, not found
console.log([4, 5, 8, 12].find(isPrime));
// 5
上面的代码: Mozilla Dev