ES6是即將到來的新版本JavaScript語言的標準,代號harmony(和諧之意,顯然沒有跟上我國的步伐,我們已經進入中國夢版本了)
箭頭操作符
如果你會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));
類的支持
ES6中添加了對類的支持,引入了class關鍵字(其實class在JavaScript中一直是保留字,目的就是考慮到可能在以后的新版本中會用到,現在終于派上用場了)。JS本身就是面向對象的,ES6中提供的類實際上只是JS原型模式的包裝。現在提供原生的class支持后,對象的創建,繼承更加直觀了,并且父類方法的調用,實例化,靜態方法和構造函數等概念都更加形象化。
//類的定義
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();
//將這個數字輸出到
consoleconsole.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 dudesayHello('Wayou');
//輸出:Hello WayousayHello2();
//輸出:Hello dudesayHello2('Wayou');
//輸出:Hello Wayou
不定參數
不定參數是在函數中使用命名參數同時接收不定數量的未命名參數。這只是一種語法糖,在以前的JavaScript代碼中我們可以通過arguments變量來達到這一目的。不定參數的格式是三個句點后跟代表所有不定參數的變量名。比如下面這個例子中,…x代表了所有傳入add函數的參數。
//將所有參數相加的函數
function add(...x){ return x.reduce((m,n)=>m+n);}
//傳遞任意個數的參數console.log(add(1,2,3));
//輸出:6console.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,1console.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并未實現,所以無法模擬調試,下面有些功能也是如此
Map,Set 和 WeakMap,WeakSet
這些是新加的集合類型,提供了更加方便的獲取屬性值的方法,不用像以前一樣用hasOwnProperty來檢查某個屬性是屬于原型鏈上的呢還是當前對象的。同時,在進行屬性值添加與獲取時有專門的get,set 方法。
Setsvar s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
Mapsvar m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
有時候我們會把對象作為一個對象的鍵用來存放屬性值,普通集合類型比如簡單對象會阻止垃圾回收器對這些作為屬性鍵存在的對象的回收,有造成內存泄漏的危險。而WeakMap,WeakSet則更加安全些,這些作為屬性鍵的對象如果沒有別的變量在引用它們,則會被回收釋放掉
Math,Number,String,Object 的新API
對Math,Number,String還有Object等添加了許多新的API。下面代碼同樣來自es6features,對這些新API進行了簡單展示。
Number.EPSILONNumber.isInteger(Infinity)
falseNumber.isNaN("NaN")
falseMath.acosh(3) //
1.762747174039086Math.hypot(3, 4) //
5Math.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 ArrayArray.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模式。
//創建
promisevar 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"});
總結
總結就是一句話,前后端差異越來越小了。