ES6(ECMAScript 6)新特征

本文基于lukehoban/es6features ,同时参考了大批博客材料,详细见文末援用。

ES6(ECMAScript 6)是行将到来的新版本JavaScript言语的范例,代号harmony(调和之意,明显没有跟上我国的步调,我们已进入中国梦版本了)。上一次范例的制定照样2009年出台的ES5。如今ES6的范例化事变正在举行中,估计会在14年12月份放出正式敲定的版本。但大部份范例已停当,且各浏览器对ES6的支撑也正在完成中。要检察ES6的支撑状况请点此。

如今想要运转ES6代码的话,可以用google/traceur-compiler将代码转译。点此接见traceur-compiler 在线版本时实编辑ES6代码并检察转换后的结果,代码运转结果会在console显现。

别的,关于Google Traceur,业界大神Addy Osmani运用前者写了个Chrome插件ES6 Tepl,装置后也可以举行ES6的测试。

固然,并非一切ES6新特征都被完成了,所以上面的要领可以测试大部份,有一些照样没法测试的。

虽然ES6都还没真正宣布,但已有效ES6重写的顺序了,种种关于ES789的提议已最先了,这你敢信。潮水不是我等群众所能追逐的。

潮水虽然太快,但我们不断下进修的步调,就不会被潮水丢下的,下面来明白下ES6中新特征,一堵新生代JS的风貌。

箭头操纵符

假如你会C#或许Java,你一定晓得lambda表达式,ES6中新增的箭头操纵符=>便有异曲同工之妙。它简化了函数的誊写。操纵符左侧为输入的参数,而右侧则是举行的操纵以及返回的值Inputs=>outputs。

我们晓得在JS中回调是常常的事,而平常回调又以匿名函数的情势涌现,每次都须要写一个function,甚是烦琐。当引入箭头操纵符后可以轻易地写回调了。请看下面的例子。

var array = [1, 2, 3];
//传统写法
array.forEach(function(v, i, a) {

console.log(v);

});
//ES6
array.forEach(v = > console.log(v));
人人可以翻开文章开首提到的traceur在线代码转译页面输入代码来检察结果。

类的支撑

ES6中增加了对类的支撑,引入了class关键字(实在class在JavaScript中一直是保留字,目的就是考虑到可能在今后的新版本中会用到,如今终究派上用场了)。JS自身就是面向对象的,ES6中供应的类实际上只是JS原型形式的包装。如今供应原生的class支撑后,对象的建立,继承越发直观了,而且父类要领的挪用,实例化,静态要领和组织函数等观点都越发形象化。

下面代码展现了类在ES6中的运用。再次烦琐一句,你可以将代码贴到traceur本身检察运转结果。

//类的定义
class Animal {

//ES6中新型组织器
constructor(name) {
    this.name = name;
}
//实例要领
sayName() {
    console.log('My name is '+this.name);
}

}
//类的继承
class Programmer extends Animal {

constructor(name) {
    //直接挪用父类组织器举行初始化
    super(name);
}
program() {
    console.log("I'm coding...");
}

}
//测试我们的类
var animal=new Animal(‘dummy’),
wayou=new Programmer(‘wayou’);
animal.sayName();//输出 ‘My name is dummy’
wayou.sayName();//输出 ‘My name is wayou’
wayou.program();//输出 ‘I’m coding…’

加强的对象字面量

对象字面量被加强了,写法越发简约与天真,同时在定义对象的时刻可以做的事变更多了。详细表如今:

可以在对象字面量内里定义原型
定义要领可以不必function关键字
直接挪用父类要领
这样一来,对象字面量与前面提到的类观点越发符合,在编写面向对象的JavaScript时越发轻松轻易了。

//经由过程对象字面量建立对象
var human = {

breathe() {
    console.log('breathing...');
}

};
var worker = {

__proto__: human, //设置此对象的原型为human,相当于继承human
company: 'freelancer',
work() {
    console.log('working...');
}

};
human.breathe();//输出 ‘breathing…’
//挪用继承来的breathe要领
worker.breathe();//输出 ‘breathing…’

字符串模板

字符串模板相对简朴易懂些。ES6中许可运用反引号 ` 来建立字符串,此种要领建立的字符串内里可以包括由美圆标记加花括号包裹的变量${vraible}。假如你运用过像C#等后端强范例言语的话,对此功用应当不会生疏。

//发生一个随机数
var num=Math.random();
//将这个数字输出到console
console.log(your num is ${num});
解构

自动剖析数组或对象中的值。比方若一个函数要返回多个值,通例的做法是返回一个对象,将每一个值做为这个对象的属性返回。但在ES6中,运用解构这一特征,可以直接返回一个数组,然后数组中的值会自动被剖析到对应吸收该值的变量中。

var [x,y]=getVal(),//函数返回值的解构

[name,,age]=['wayou','male','secrect'];//数组解构

function getVal() {

return [ 1, 2 ];

}

console.log(‘x:’+x+’, y:’+y);//输出:x:1, y:2
console.log(‘name:’+name+’, age:’+age);//输出: name:wayou, age:secrect
参数默许值,不定参数,拓展参数

默许参数值

如今可以在定义函数的时刻指定参数的默许值了,而不必像之前那样经由过程逻辑或操纵符来到达目的了。

function sayHello(name){

//传统的指定默许参数的体式格局
var name=name||'dude';
console.log('Hello '+name);

}
//运用ES6的默许参数
function sayHello2(name=’dude’){

console.log(`Hello ${name}`);

}
sayHello();//输出:Hello dude
sayHello(‘Wayou’);//输出:Hello Wayou
sayHello2();//输出:Hello dude
sayHello2(‘Wayou’);//输出:Hello Wayou

不定参数

不定参数是在函数中运用定名参数同时吸收不定数目的未定名参数。这只是一种语法糖,在之前的JavaScript代码中我们可以经由过程arguments变量来到达这一目的。不定参数的花样是三个句点后跟代表一切不定参数的变量名。比方下面这个例子中,…x代表了一切传入add函数的参数。

//将一切参数相加的函数
function add(…x){

return x.reduce((m,n)=>m+n);

}
//通报恣意个数的参数
console.log(add(1,2,3));//输出:6
console.log(add(1,2,3,4,5));//输出:15

拓展参数

拓展参数则是另一种情势的语法糖,它许可通报数组或许类数组直接做为函数的参数而不必经由过程apply。

var people=[‘Wayou’,’John’,’Sherlock’];
//sayHello函数原本吸收三个零丁的参数人妖,人二和人三
function sayHello(people1,people2,people3){

console.log(`Hello ${people1},${people2},${people3}`);

}
//然则我们将一个数组以拓展参数的情势通报,它能很好地映射到每一个零丁的参数
sayHello(…people);//输出:Hello Wayou,John,Sherlock

//而在之前,假如须要通报数组当参数,我们须要运用函数的apply要领
sayHello.apply(null,people);//输出:Hello Wayou,John,Sherlock
let与const 关键字

可以把let算作var,只是它定义的变量被限定在了特定局限内才运用,而脱离这个局限则无效。const则很直观,用来定义常量,即没法被变动值的变量。

for (let i=0;i<2;i++)console.log(i);//输出: 0,1
console.log(i);//输出:undefined,严厉形式下会报错
for of 值遍历

我们都晓得for in 轮回用于遍历数组,类数组或对象,ES6中新引入的for of轮回功用类似,差别的是每次轮回它供应的不是序号而是值。

var someArray = [ “a”, “b”, “c” ];

for (v of someArray) {

console.log(v);//输出 a,b,c

}
注重,此功用google traceur并未完成,所以没法模仿调试,下面有些功用也是云云

iterator, generator

这一部份的内容有点生涩,概况可以拜见这里。以下是些基础观点。

iterator:它是这么一个对象,具有一个next要领,这个要领返回一个对象{done,value},这个对象包括两个属性,一个布尔范例的done和包括恣意值的value
iterable: 这是这么一个对象,具有一个obj[@@iterator]要领,这个要领返回一个iterator
generator: 它是一种特别的iterator。反的next要领可以吸收一个参数而且返回值取决与它的组织函数(generator function)。generator同时具有一个throw要领
generator 函数: 即generator的组织函数。此函数内可以运用yield关键字。在yield涌现的处所可以经由过程generator的next或throw要领向外界通报值。generator 函数是经由过程function*来声明的
yield 关键字:它可以停息函数的实行,随后可以再进进入函数继承实行
模块

在ES6范例中,JavaScript原生支撑module了。这类将JS代码分割成差别功用的小块举行模块化的观点是在一些三方范例中流行起来的,比方CommonJS和AMD形式。

将差别功用的代码离别写在差别文件中,各模块只需导出大众接口部份,然后经由过程模块的导入的体式格局可以在其他处所运用。下面的例子来自tutsplus:

// point.js
module “point” {

export class Point {
    constructor (x, y) {
        public x = x;
        public y = y;
    }
}

}

// myapp.js
//声明援用的模块
module point from “/point.js”;
//这里可以看出,只管声清楚明了援用的模块,照样可以经由过程指定须要的部份举行导入
import Point from “point”;

var origin = new Point(0, 0);
console.log(origin);
Map,Set 和 WeakMap,WeakSet

这些是新加的鸠合范例,供应了越发轻易的猎取属性值的要领,不必像之前一样用hasOwnProperty来搜检某个属性是属于原型链上的呢照样当前对象的。同时,在举行属性值增加与猎取时有特地的get,set 要领。

下方代码来自es6feature

// Sets
var s = new Set();
s.add(“hello”).add(“goodbye”).add(“hello”);
s.size === 2;
s.has(“hello”) === true;

// Maps
var m = new Map();
m.set(“hello”, 42);
m.set(s, 34);
m.get(s) == 34;
有时刻我们会把对象作为一个对象的键用来寄存属性值,一般鸠合范例比方简朴对象会阻挠渣滓接纳器对这些作为属性键存在的对象的接纳,有形成内存走漏的风险。而WeakMap,WeakSet则越发平安些,这些作为属性键的对象假如没有别的变量在援用它们,则会被接纳释放掉,详细还看下面的例子。

正文代码来自es6feature

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });//由于增加到ws的这个暂时对象没有其他变量援用它,所以ws不会保留它的值,也就是说此次增加实在没有意义

Proxies

Proxy可以监听对象身上发生了什么事变,并在这些事变发生后实行一些响应的操纵。一会儿让我们对一个对象有了很强的追踪才能,同时在数据绑定方面也很有效处。

以下例子借用自这里。

//定义被侦听的目的对象
var engineer = { name: ‘Joe Sixpack’, salary: 50 };
//定义处置惩罚顺序
var interceptor = {
set: function (receiver, property, value) {

console.log(property, 'is changed to', value);
receiver[property] = value;

}
};
//建立代办以举行侦听
engineer = Proxy(engineer, interceptor);
//做一些修改来触发代办
engineer.salary = 60;//控制台输出:salary is changed to 60
上面代码我已加了诠释,这里进一步诠释。关于处置惩罚顺序,是在被侦听的对象身上发生了响应事宜以后,处置惩罚顺序内里的要领就会被挪用,上面例子中我们设置了set的处置惩罚函数,表明,假如我们侦听的对象的属性被变动,也就是被set了,那这个处置惩罚顺序就会被挪用,同时经由过程参数可以得知是哪一个属性被变动,变动为了什么值。

Symbols

我们晓得对象实际上是键值对的鸠合,而键一般来说是字符串。而如今除了字符串外,我们还可以用symbol这类值来做为对象的键。Symbol是一种基础范例,像数字,字符串另有布尔一样,它不是一个对象。Symbol 经由过程挪用symbol函数发生,它吸收一个可选的名字参数,该函数返回的symbol是唯一的。以后就可以用这个返回值做为对象的键了。Symbol还可以用来建立私有属性,外部没法直接接见由symbol做为键的属性值。

以下例子来自es6features

(function() {

// 建立symbol
var key = Symbol(“key”);

function MyClass(privateData) {

this[key] = privateData;

}

MyClass.prototype = {

doStuff: function() {
  ... this[key] ...
}

};

})();

var c = new MyClass(“hello”)
c[“key”] === undefined//没法接见该属性,由于是私有的

Math,Number,String,Object 的新API

对Math,Number,String另有Object等增加了许多新的API。下面代码一样来自es6features,对这些新API举行了简朴展现。

Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN(“NaN”) // false

Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) – 1, Math.pow(2, 32) – 2) // 2

“abcde”.contains(“cd”) // true
“abc”.repeat(3) // “abcabcabc”

Array.from(document.querySelectorAll(‘*’)) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(…), but without special one-arg behavior
[0, 0, 0].fill(7, 1) // [0,7,7]
[1,2,3].findIndex(x => x == 2) // 1
[“a”, “b”, “c”].entries() // iterator [0, “a”], [1,”b”], [2,”c”]
[“a”, “b”, “c”].keys() // iterator 0, 1, 2
[“a”, “b”, “c”].values() // iterator “a”, “b”, “c”

Object.assign(Point, { origin: new Point(0,0) })

Promises

Promises是处置惩罚异步操纵的一种形式,之前在许多三方库中有完成,比方jQuery的deferred 对象。当你提议一个异步要求,并绑定了.when(), .done()等事宜处置惩罚顺序时,实在就是在运用promise形式。

//建立promise
var promise = new Promise(function(resolve, reject) {

// 举行一些异步或耗时操纵
if ( /*假如胜利 */ ) {
    resolve("Stuff worked!");
} else {
    reject(Error("It broke"));
}

});
//绑定处置惩罚顺序
promise.then(function(result) {

//promise胜利的话会实行这里
console.log(result); // "Stuff worked!"

}, function(err) {

//promise失利会实行这里
console.log(err); // Error: "It broke"

});
总结

总结就是一句话,前后端差别愈来愈小了。

REFERENCE

Google traceur online compiler http://google.github.io/trace…
array destruction http://ariya.ofilabs.com/2013…
class http://www.joezimjs.com/javas…
enhanced object literal http://maximilianhoffmann.com…
parameters http://globaldev.co.uk/2013/1…
let keyword http://globaldev.co.uk/2013/0…
for of iterator https://developer.mozilla.org…
the Iterator protocol https://developer.mozilla.org…
generators https://developer.mozilla.org…*
ES6 Iterators, Generators, and Iterables http://domenic.me/2013/09/06/…
proxies http://ariya.ofilabs.com/2013…
symbols http://tc39wiki.calculist.org…
promise http://www.html5rocks.com/en/…
8 cool features in ES6 http://code.tutsplus.com/tuto… (此文章毛病较多)
Feel free to repost but keep the link to this page please!

分类: JavaScript

    原文作者:夏荷jn
    原文地址: https://segmentfault.com/a/1190000008816864
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞