@(StuRep)javascript
解構:ES6容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被成爲解構。以下:java
//ES5 var a = 1; var b = 2; var c = 3; //ES6 var [a, b, c] = [1, 2, 3]; //嵌套 let [foo, [[bar], baz]] = [1, [[2], 3]]; foo;//1 bar;//2 baz;//3 //若是等號右邊不是能夠遍歷的結構,就沒法匹配就會報錯。
解構賦值是容許設置默認值的,在ES6內部使用'==='來判斷一個位置是否有值。因此,若是一個數組成員不嚴格等於undefined,默認值是不會生效的。例如:正則表達式
[x, y = 'b'] = ['a', undefined];//x='a',y='b' [x = 1] = [null];//x=null
默認值能夠引用解構賦值的其餘變量,但該變量必須已經聲明。例如:編程
let [x = 1, y = x] = []; //x=1; y=1 let [x = 1, y = x] = [2]; //x=2; y=2 let [x = 1, y = x] = [1, 2]; //x=1; y=2 let [x = y, y = 1] = []; //報錯,由於x在使用y做爲其默認值的時候y尚未被聲明
對象的解構賦值:json
var {foo, bar} = {foo: "aaa", bar:"bbb"}; foo //"aaa" bar //"bbb"
對象的解構賦值和數組有一個重要的不一樣:數組的元素是按次序排列的,變量的取值由它的位置來決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。
對象的解構賦值能夠很方便地將現有對象的方法賦值到某個變量。例如:數組
let {log, sin, cos} = Math; //這樣就能夠把取對數、正弦、餘弦3個方法賦值到對應的變量上面,用起來很方便;
字符串也能夠解構賦值,由於字符串會被轉換成一個相似數組的對象。例如:瀏覽器
const [a, b, c, d, e] = 'hello'; a // 'h' b // 'e' c // 'l' d // 'l' e // 'o' let {length : len} = 'hello'; len //5
函數參數也能夠解構賦值,例如:babel
function add([x,y]){ return x + y; } add([1, 2]) //3
變量的解構賦值的用途不少,簡潔易讀:app
[x, y] = [y, x]
;function example(){ return [1, 2, 3]; } var [a, b, c] = example();
函數參數的定義;編程語言
//有序 function f([x, y, z]){...}; f([1, 2, 3]); //無序 function f({x, y, z}){...}; f({z:3, y:2, x:1});
ES6增強了對Unicode的支持,而且擴展了字符串對象。
includes(),startsWith(),endsWith()方法。JS中只有indexOf方法能夠用來肯定一個字符串是否包含在另外一個字符串中,ES6又提供了三種方法:
padStart(),padEnd():ES7推出了字符串補全長度的功能。若是某個字符串長度未達指定長度,會在頭部或尾部補全。padStart用於頭部補全,padEnd用於尾部補全。若是原字符串的長度大於或等於指定的最小長度,則返回原字符串。例如:
'x'.padStart(5, 'ab') //'ababx' 'x'.padStart(4, 'ab') //'abax' 'x'.padEnd(5, 'ab') //'xabab' 'x'.padEnd(4, 'ab') //'xaba' 'xxx'.padStart(2, 'ab') //'xxx'
var regex = new RegExp("xyz", "i");
。在ES6中容許RegExp構造函數接受正則表達式做爲參數,這時會返回一個原有正則表達式的拷貝。ES6新增了使用大括號表示Unicode字符的表示法,這種表示法在正則表達式中必須加上u修飾符才能識別。例如:
/\u{61}/.test('a'); //false /\u{61}/u.test('a'); //true
Number.parseInt(),Number.parseFloat():ES6將全局方法parseInt()和parseFloat()移植到了Number對象上。這樣是爲了逐步減小全局性的方法,使語言逐步模塊化。
//ES5 parseInt(''); //ES6 Number.parseInt(''); Number.parseInt === parseInt; //true
Math對象的擴展,ES6在Math對象上新增了17個與數學相關的方法:
Math.imul(-1, 8); //-8
Math.hypot(3, 4);//5
Array.of(3, 11, 8) //[3,11,8]
new Array(3).fill(7) //[7,7,7]
x = x || "XXX"
這樣的寫法,ES6容許爲函數的參數設置默認值,就能夠這樣寫function test(x, y = "xxx"){};
,這樣的設計還有一個好處就是開發人員閱讀別人的代碼一眼就能看出來在調用這個接口哪些參數是可省的。此外,這種寫法還能夠和解構賦值結合使用,很是靈活。(function(a=5){}).length;//0
ES6引入了rest參數(形式爲"...變量名"),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。rest參數搭配的變量是一個數組,該變量將多餘的參數放入其中,例如:
function add(...values){ let sum = 0; for(var val of values){ sum += val; } return sum; } add(2, 5, 3); //10 //add函數是一個求和函數,利用rest參數能夠向該函數傳入任意數目的參數。
console.log(1,...[2,3,4],5);//1 2 3 4 5
;擴展運算符替代數組的apply方法,擴展運算符能夠直接把數組拆開,例如:
//ES5 function f(x,y,z){}; var args = [0,1,2]; f.apply(null, args); //ES6 function f(x,y,z){}; var args = [0,1,2]; f(...args);
擴展運算符提供了數組合並的新方法:
//ES5 [1,2].concat(more) //ES6 [1,2, ...more]
箭頭函數:ES6容許使用"箭頭"(=>)定義函數,例如:
var sum = (num1, num2) => num1 + num2; //等價於 var sum = function(num1, num2){ return num1 + num2; }
使用箭頭函數有幾個注意點:
foo::bar(...arguments)等價於bar.apply(foo,arguments;)
。感受函數綁定這個設計很是的便捷,不須要在顯式的去綁定一下上下文,期待該提案的經過(目前babel已經支持這個寫法了);尾遞歸:函數調用自身稱爲遞歸,若是尾調用自身就稱爲尾遞歸。遞歸很是耗費內存,由於須要同時保存成千上百個調用幀,很容易stackoverflow。但對於尾遞歸來講,只存在一個調用幀,因此永遠不會發生「棧溢出」錯誤。例如:
//這是一個階乘函數,計算n的階乘,最多須要保存n個調用記錄,複雜度爲O(n)。 function factorial(n){ if(n === 1) return 1; return n * factorial(n - 1); } //改寫成尾遞歸,只保用一個調用記錄,則複雜度爲O(1); function factorial(n, totla){ if(n === 1) return total; return factorial(n - 1, n * total); }
因而可知‘尾調用優化’對於遞歸操做的意義很是重大,因此一些函數式編程語言將其寫入了語言規格。ES6也是如此,第一次明確規定,全部ECMAScript的實現,都必須部署‘尾調用優化’。這就是說,在ES6中,只要使用尾遞歸,就不會棧溢出,節省內存。
(未完待續......)