<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## 概述 ECMAScript 6 是JavaScript的下一代標準,正處在快速開發之中,大部分已經完成了,預計將在2014年正式發布。Mozilla將在這個標準的基礎上,推出JavaScript 2.0。 ECMAScript 6的目標,是使得JavaScript可以用來編寫復雜的應用程序、函數庫和代碼的自動生成器(code generator)。 最新的瀏覽器已經部分支持ECMAScript 6 的語法,可以通過[《ECMAScript 6 瀏覽器兼容表》](http://kangax.github.io/es5-compat-table/es6/)查看瀏覽器支持情況。 下面對ECMAScript 6新增的語法特性逐一介紹。由于ECMAScript 6的正式標準還未出臺,所以以下內容隨時可能發生變化,不一定是最后的版本。 ## 使用ECMAScript 6的方法 目前,V8引擎已經部署了ECMAScript 6的部分特性。使用node.js 0.11版,就可以體驗這些特性。 node.js 0.11版的一種比較方便的使用方法,是使用版本管理工具[nvm](https://github.com/creationix/nvm)。下載nvm以后,進入項目目錄,運行下面的命令,激活nvm。 ~~~ source nvm.sh ~~~ 然后,指定node運行版本。 ~~~ nvm use 0.11 ~~~ 最后,用--harmony參數進入node運行環境,就可以在命令行下體驗ECMAScript 6了。 ~~~ node --harmony ~~~ 另外,可以使用Google的[Traceur](https://github.com/google/traceur-compiler)([在線轉換工具](http://google.github.io/traceur-compiler/demo/repl.html)),將ES6代碼編譯為ES5。 ~~~ # 安裝 npm install -g traceur # 運行ES6文件 traceur /path/to/es6 # 將ES6文件轉為ES5文件 traceur --script /path/to/es6 --out /path/to/es5 ~~~ ## 數據類型 ### let命令 (1)概述 ECMAScript 6新增了let命令,用來聲明變量。它的用法類似于var,但是所聲明的變量,只在let命令所在的代碼塊內有效。 ~~~ { let a = 10; var b = 1; } a // ReferenceError: a is not defined. b //1 ~~~ 上面代碼在代碼塊之中,分別用let和var聲明了兩個變量。然后在代碼塊之外調用這兩個變量,結果let聲明的變量報錯,var聲明的變量返回了正確的值。這表明,let聲明的變量只在它所在的代碼塊有效。 下面的代碼如果使用var,最后輸出的是9。 ~~~ var a = []; for (var i = 0; i < 10; i++) { var c = i; a[i] = function () { console.log(c); }; } a[6](); // 9 ~~~ 如果使用let,聲明的變量僅在塊級作用域內有效,最后輸出的是6。 ~~~ var a = []; for (var i = 0; i < 10; i++) { let c = i; a[i] = function () { console.log(c); }; } a[6](); // 6 ~~~ 注意,let不允許在相同作用域內,重復聲明同一個變量。 ~~~ // 報錯 { let a = 10; var a = 1; } // 報錯 { let a = 10; let a = 1; } ~~~ (2)塊級作用域 let實際上為JavaScript新增了塊級作用域。 ~~~ function f1() { let n = 5; if (true) { let n = 10; } console.log(n); // 5 } ~~~ 上面的函數有兩個代碼塊,都聲明了變量n,運行后輸出5。這表示外層代碼塊不受內層代碼塊的影響。如果使用var定義變量n,最后輸出的值就是10。 塊級作用域的出現,實際上使得獲得廣泛應用的立即執行函數(IIFE)不再必要了。 ~~~ // IIFE寫法 (function () { var tmp = ...; ... }()); // 塊級作用域寫法 { let tmp = ...; ... } ~~~ (3)不存在變量提升 需要注意的是,let聲明的變量不存在“變量提升”現象。 ~~~ console.log(x); let x = 10; ~~~ 上面代碼運行后會報錯,表示x沒有定義。如果用var聲明x,就不會報錯,輸出結果為undefined。 ### const命令 const也用來聲明變量,但是聲明的是常量。一旦聲明,常量的值就不能改變。 ~~~ const PI = 3.1415; PI // 3.1415 PI = 3; PI // 3.1415 const PI = 3.1; PI // 3.1415 ~~~ 上面代碼表明改變常量的值是不起作用的。需要注意的是,對常量重新賦值不會報錯,只會默默地失敗。 > const的作用域與var命令相同:如果在全局環境聲明,常量就在全局環境有效;如果在函數內聲明,常量就在函數體內有效。 ### Set數據結構 ES6提供了新的數據結構Set。它類似于數組,但是成員的值都是唯一的,沒有重復的值。 Set本身是一個構造函數,用來生成Set數據結構。 ~~~ var s = new Set(); [2,3,5,4,5,2,2].map(x => s.add(x)) for (i of s) {console.log(i)} // 2 3 4 5 ~~~ 上面代碼表示,set數據結構不會添加重復的值。 set數據結構有以下屬性和方法: * size:返回成員總數。 * add(value):添加某個值。 * delete(value):刪除某個值。 * has(value):返回一個布爾值,表示該值是否為set的成員。 * clear():清除所有成員。 ~~~ s.add("1").add("2").add("2"); // 注意“2”被加入了兩次 s.size // 2 s.has("1") // true s.has("2") // true s.has("3") // false s.delete("2"); s.has("2") // false ~~~ ### Map數據結構 ES6還提供了map數據結構。它類似于對象,就是一個鍵值對的集合,但是“鍵”的范圍不限于字符串,甚至對象也可以當作鍵。 ~~~ var m = new Map(); o = {p: "Hello World"}; m.set(o, "content") console.log(m.get(o)) // "content" ~~~ 上面代碼將一個對象當作m的一個鍵。 Map數據結構有以下屬性和方法。 * size:返回成員總數。 * set(key, value):設置一個鍵值對。 * get(key):讀取一個鍵。 * has(key):返回一個布爾值,表示某個鍵是否在Map數據結構中。 * delete(key):刪除某個鍵。 * clear():清除所有成員。 ~~~ var m = new Map(); m.set("edition", 6) // 鍵是字符串 m.set(262, "standard") // 鍵是數值 m.set(undefined, "nah") // 鍵是undefined var hello = function() {console.log("hello");} m.set(hello, "Hello ES6!") // 鍵是函數 m.has("edition") // true m.has("years") // false m.has(262) // true m.has(undefined) // true m.has(hello) // true m.delete(undefined) m.has(undefined) // false m.get(hello) // Hello ES6! m.get("edition") // 6 ~~~ ### rest(...)運算符 (1)基本用法 ES6引入rest運算符(...),用于獲取函數的多余參數,這樣就不需要使用arguments.length了。rest運算符后面是一個數組變量,該變量將多余的參數放入數組中。 ~~~ function add(...values) { let sum = 0; for (var val of values) { sum += val; } return sum; } add(2, 5, 3) // 10 ~~~ 上面代碼的add函數是一個求和函數,利用rest運算符,可以向該函數傳入任意數目的參數。 下面是一個利用rest運算符改寫數組push方法的例子。 ~~~ function push(array, ...items) { items.forEach(function(item) { array.push(item); console.log(item); }); } var a = []; push(a, "a1", "a2", "a3", "a4"); ~~~ (2)將數組轉為參數序列 rest運算符不僅可以用于函數定義,還可以用于函數調用。 ~~~ function f(s1, s2, s3, s4, s5) { console.log(s1 + s2 + s3 + s4 +s5); } var a = ["a2", "a3", "a4", "a5"]; f("a1", ...a) // a1a2a3a4a5 ~~~ 從上面的例子可以看出,rest運算符的另一個重要作用是,可以將數組轉變成正常的參數序列。利用這一點,可以簡化求出一個數組最大元素的寫法。 ~~~ // ES5 Math.max.apply(null, [14, 3, 77]) // ES6 Math.max(...[14, 3, 77]) // 等同于 Math.max(14, 3, 77); ~~~ 上面代碼表示,由于JavaScript不提供求數組最大元素的函數,所以只能套用Math.max函數,將數組轉為一個參數序列,然后求最大值。有了rest運算符以后,就可以直接用Math.max了。 ### 遍歷器(Iterator) 遍歷器(Iterator)是一種協議,任何對象都可以部署遍歷器協議,從而使得for...of循環可以遍歷這個對象。 遍歷器協議規定,任意對象只要部署了next方法,就可以作為遍歷器,但是next方法必須返回一個包含value和done兩個屬性的對象。其中,value屬性當前遍歷位置的值,done屬性是一個布爾值,表示遍歷是否結束。 ~~~ function makeIterator(array){ var nextIndex = 0; return { next: function(){ return nextIndex < array.length ? {value: array[nextIndex++], done: false} : {done: true}; } } } var it = makeIterator(['a', 'b']); it.next().value // 'a' it.next().value // 'b' it.next().done // true ~~~ 下面是一個無限運行的遍歷器的例子。 ~~~ function idMaker(){ var index = 0; return { next: function(){ return {value: index++, done: false}; } } } var it = idMaker(); it.next().value // '0' it.next().value // '1' it.next().value // '2' // ... ~~~ ### generator 函數 上一部分的遍歷器,用來依次取出集合中的每一個成員,但是某些情況下,我們需要的是一個內部狀態的遍歷器。也就是說,每調用一次遍歷器,對象的內部狀態發生一次改變(可以理解成發生某些事件)。ECMAScript 6 引入了generator函數,作用就是返回一個內部狀態的遍歷器,主要特征是函數內部使用了yield語句。 當調用generator函數的時候,該函數并不執行,而是返回一個遍歷器(可以理解成暫停執行)。以后,每次調用這個遍歷器的next方法,就從函數體的頭部或者上一次停下來的地方開始執行(可以理解成恢復執行),直到遇到下一個yield語句為止,并返回該yield語句的值。 ECMAScript 6草案定義的generator函數,需要在function關鍵字后面,加一個星號。然后,函數內部使用yield語句,定義遍歷器的每個成員。 ~~~ function* helloWorldGenerator() { yield 'hello'; yield 'world'; } ~~~ yield有點類似于return語句,都能返回一個值。區別在于每次遇到yield,函數返回緊跟在yield后面的那個表達式的值,然后暫停執行,下一次從該位置繼續向后執行,而return語句不具備位置記憶的功能。 上面代碼定義了一個generator函數helloWorldGenerator,它的遍歷器有兩個成員“hello”和“world”。調用這個函數,就會得到遍歷器。 ~~~ var hw = helloWorldGenerator(); ~~~ 執行遍歷器的next方法,則會依次遍歷每個成員。 ~~~ hw.next() // { value: 'hello', done: false } hw.next() // { value: 'world', done: false } hw.next() // { value: undefined, done: true } hw.next() // Error: Generator has already finished // at GeneratorFunctionPrototype.next (native) // at repl:1:3 // at REPLServer.defaultEval (repl.js:129:27) // ... ~~~ 上面代碼一共調用了四次next方法。 * 第一次調用:函數開始執行,直到遇到第一句yield語句為止。next方法返回一個對象,它的value屬性就是當前yield語句的值hello,done屬性的值false,表示遍歷還沒有結束。 * 第二次調用:函數從上次yield語句停下的地方,一直執行到下一個yield語句。next方法返回一個對象,它的value屬性就是當前yield語句的值world,done屬性的值false,表示遍歷還沒有結束。 * 第三次調用:函數從上次yield語句停下的地方,一直執行到函數結束。next方法返回一個對象,它的value屬性就是函數最后的返回值,由于上例的函數沒有return語句(即沒有返回值),所以value屬性的值為undefined,done屬性的值true,表示遍歷已經結束。 * 第四次調用:由于此時函數已經運行完畢,next方法直接拋出一個錯誤。 遍歷器的本質,其實是使用yield語句暫停執行它后面的操作,當調用next方法時,再繼續往下執行,直到遇到下一個yield語句,并返回該語句的值,如果直到運行結束。 如果next方法帶一個參數,該參數就會被當作上一個yield語句的返回值。 ~~~ function* f() { for(var i=0; true; i++) { var reset = yield i; if(reset) { i = -1; } } } var g = f(); g.next() // { value: 0, done: false } g.next() // { value: 1, done: false } g.next(true) // { value: 0, done: false } ~~~ 上面代碼先定義了一個可以無限運行的generator函數f,如果next方法沒有參數,正常情況下返回一個遞增的i;如果next方法有參數,則上一次yield語句的返回值將會等于該參數。如果該參數為true,則會重置i的值。 generator函數的這種暫停執行的效果,意味著可以把異步操作寫在yield語句里面,等到調用next方法時再往后執行。這實際上等同于不需要寫回調函數了,因為異步操作的后續操作可以放在yield語句下面,反正要等到調用next方法時再執行。所以,generator函數的一個重要實際意義就是用來處理異步操作,改寫回調函數。 ~~~ function* loadUI() { showLoadingScreen(); yield loadUIDataAsynchronously(); hideLoadingScreen(); } ~~~ 上面代碼表示,第一次調用loadUI函數時,該函數不會執行,僅返回一個遍歷器。下一次對該遍歷器調用next方法,則會顯示登錄窗口,并且異步加載數據。再一次使用next方法,則會隱藏登錄窗口。可以看到,這種寫法的好處是所有登錄窗口的邏輯,都被封裝在一個函數,按部就班非常清晰。 下面是一個利用generator函數,實現斐波那契數列的例子。 ~~~ function* fibonacci() { var previous = 0, current = 1; while (true) { var temp = previous; previous = current; current = temp + current; yield current; } } for (var i of fibonacci()) { console.log(i); } // 1, 2, 3, 5, 8, 13, ..., ~~~ 下面是利用for...of語句,對斐波那契數列的另一種實現。 ~~~ function* fibonacci() { let [prev, curr] = [0, 1]; for (;;) { [prev, curr] = [curr, prev + curr]; yield curr; } } for (n of fibonacci()) { if (n > 1000) break; console.log(n); } ~~~ 從上面代碼可見,使用for...of語句時不需要使用next方法。 這里需要注意的是,yield語句運行的時候是同步運行,而不是異步運行(否則就失去了取代回調函數的設計目的了)。實際操作中,一般讓yield語句返回Promises對象。 ~~~ var Q = require('q'); function delay(milliseconds) { var deferred = Q.defer(); setTimeout(deferred.resolve, milliseconds); return deferred.promise; } function *f(){ yield delay(100); }; ~~~ 上面代碼yield語句返回的就是一個Promises對象。 如果有一系列任務需要全部完成后,才能進行下一步操作,yield語句后面可以跟一個數組。下面就是一個例子。 ~~~ function *f() { var urls = [ 'http://example.com/', 'http://twitter.com/', 'http://bbc.co.uk/news/' ]; var arrayOfPromises = urls.map(someOperation); var arrayOfResponses = yield arrayOfPromises; this.body = "Results"; for (var i = 0; i < urls.length; i++) { this.body += '\n' + urls[i] + ' response length is ' + arrayOfResponses[i].body.length; } }; ~~~ ### 原生對象的擴展 ES6對JavaScript的原生對象,進行了擴展,提供了一系列新的屬性和方法。 ~~~ 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) }) ~~~ ## 語法糖 ECMAScript 6提供了很多JavaScript語法的便捷寫法。 ### 二進制和八進制表示法 ES6提供了二進制和八進制數值的新的寫法,分別用前綴0b和0o表示。 ~~~ 0b111110111 === 503 // true 0o767 === 503 // true ~~~ ### 增強的對象寫法 ES6允許直接寫入變量和函數,作為對象的屬性和方法。這樣的書寫更加簡潔。 ~~~ var Person = { name: '張三', //等同于birth: birth birth, // 等同于hello: function ()... hello() { console.log('我的名字是', this.name); } }; ~~~ ### 箭頭函數(arrow) (1)定義 ES6允許使用“箭頭”(=>)定義函數。 ~~~ var f = v => v; ~~~ 上面的箭頭函數等同于: ~~~ var f = function(v) { return v; }; ~~~ 如果箭頭函數不需要參數或需要多個參數,就使用一個圓括號代表參數部分。 ~~~ var f = () => 5; // 等同于 var f = function (){ return 5 }; var sum = (num1, num2) => num1 + num2; // 等同于 var sum = function(num1, num2) { return num1 + num2; }; ~~~ 如果箭頭函數的代碼塊部分多于一條語句,就要使用大括號將它們括起來,并且使用return語句返回。 ~~~ var sum = (num1, num2) => { return num1 + num2; } ~~~ 由于大括號被解釋為代碼塊,所以如果箭頭函數直接返回一個對象,必須在對象外面加上括號。 ~~~ var getTempItem = id => ({ id: id, name: "Temp" }); ~~~ (2)實例:回調函數的簡化 箭頭函數的一個用處是簡化回調函數。 ~~~ // 正常函數寫法 [1,2,3].map(function (x) { return x * x; }); // 箭頭函數寫法 [1,2,3].map(x => x * x); ~~~ 另一個例子是 ~~~ // 正常函數寫法 var result = values.sort(function(a, b) { return a - b; }); // 箭頭函數寫法 var result = values.sort((a, b) => a - b); ~~~ (3)注意點 箭頭函數有幾個使用注意點。 * 函數體內的this對象,綁定定義時所在的對象,而不是使用時所在的對象。 * 不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。 * 不可以使用arguments對象,該對象在函數體內不存在。 關于this對象,下面的代碼將它綁定定義時的對象。 ~~~ var handler = { id: "123456", init: function() { document.addEventListener("click", event => this.doSomething(event.type), false); }, doSomething: function(type) { console.log("Handling " + type + " for " + this.id); } }; ~~~ 上面代碼的init和doSomething方法中,都使用了箭頭函數,它們中的this都綁定handler對象。否則,doSomething方法內部的this對象就指向全局對象,運行時會報錯。 ### 函數參數的默認值 ECMAScript 6 允許為函數的參數設置默認值。 ~~~ function Point(x = 0, y = 0) { this.x = x; this.y = y; } var p = new Point(); // p = { x:0, y:0 } ~~~ ### 模板字符串 模板字符串(template string)是增強版的字符串,即可以當作普通字符串使用,也可以在字符串中嵌入變量。它用反引號(`)標識。 ~~~ // 普通字符串 `In JavaScript '\n' is a line-feed.` // 多行字符串 `In JavaScript this is not legal.` // 字符串中嵌入變量 var name = "Bob", time = "today"; `Hello ${name}, how are you ${time}?` var x = 1; var y = 2; console.log(`${ x } + ${ y } = ${ x + y}`) // "1 + 2 = 3" ~~~ ### for...of循環 JavaScript原有的for...in循環,只能獲得對象的鍵名,不能直接獲取鍵值。ES6提供for...of循環,允許遍歷獲得鍵值。 ~~~ var arr = ["a", "b", "c", "d"]; for (a in arr) { console.log(a); } // 0 // 1 // 2 // 3 for (a of arr) { console.log(a); } // a // b // c // d ~~~ 上面代碼表明,for...in循環讀取鍵名,for...of循環讀取鍵值。 for...of循環還可以遍歷對象。 ~~~ var es6 = { edition: 6, committee: "TC39", standard: "ECMA-262" }; for (e in es6) { console.log(e); } // edition // committee // standard var engines = Set(["Gecko", "Trident", "Webkit", "Webkit"]); for (var e of engines) { console.log(e); } // Gecko // Trident // Webkit var es6 = new Map(); es6.set("edition", 6); es6.set("committee", "TC39"); es6.set("standard", "ECMA-262"); for (var [name, value] of es6) { console.log(name + ": " + value); } // edition: 6 // committee: TC39 // standard: ECMA-262 ~~~ 上面代碼一共包含三個例子,第一個是for...in循環的例子,后兩個是for...of循環的例子。最后一個例子是同時遍歷對象的鍵名和鍵值。 ### 數組推導 (1)基本用法 ES6提供簡潔寫法,允許直接通過現有數組生成新數組,這被稱為數組推導(array comprehension)。 ~~~ var a1 = [1, 2, 3, 4]; var a2 = [i * 2 for (i of a1)]; a2 // [2, 4, 6, 8] ~~~ 上面代碼表示,通過for...of結構,數組a2直接在a1的基礎上生成。 數組推導可以替代map和filter方法。 ~~~ [for (i of [1, 2, 3]) i * i]; // 等價于 [1, 2, 3].map(function (i) { return i * i }); [i for (i of [1,4,2,3,-8]) if (i < 3)]; // 等價于 [1,4,2,3,-8].filter(function(i) { return i < 3 }); ~~~ 上面代碼說明,模擬map功能只要單純的for...of循環就行了,模擬filter功能除了for...of循環,還必須加上if語句。 (2)多重推導 新引入的for...of結構,可以直接跟在表達式的前面或后面,甚至可以在一個數組推導中,使用多個for...of結構。 ~~~ var a1 = ["x1", "y1"]; var a2 = ["x2", "y2"]; var a3 = ["x3", "y3"]; [(console.log(s + w + r)) for (s of a1) for (w of a2) for (r of a3)]; // x1x2x3 // x1x2y3 // x1y2x3 // x1y2y3 // y1x2x3 // y1x2y3 // y1y2x3 // y1y2y3 ~~~ 上面代碼在一個數組推導之中,使用了三個for...of結構。 需要注意的是,數組推導的方括號構成了一個單獨的作用域,在這個方括號中聲明的變量類似于使用let語句聲明的變量。 (3)字符串推導 由于字符串可以視為數組,因此字符串也可以直接用于數組推導。 ~~~ [c for (c of 'abcde') if (/[aeiou]/.test(c))].join('') // 'ae' [c+'0' for (c of 'abcde')].join('') // 'a0b0c0d0e0' ~~~ 上面代碼使用了數組推導,對字符串進行處理。 上一部分的數組推導有一個缺點,就是新數組會立即在內存中生成。這時,如果原數組是一個很大的數組,將會非常耗費內存。 ### 多變量賦值 ES6允許簡潔地對多變量賦值。正常情況下,將數組元素賦值給多個變量,只能一次次分開賦值。 ~~~ var a = 1; var b = 2; var c = 3; ~~~ ES6允許寫成下面這樣。 ~~~ var [a, b, c] = [1, 2, 3]; ~~~ 本質上,這種寫法屬于模式匹配,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。下面是一些嵌套數組的例子。 ~~~ var [foo, [[bar], baz]] = [1, [[2], 3]] var [,,third] = ["foo", "bar", "baz"] var [head, ...tail] = [1, 2, 3, 4] ~~~ 它還可以接受默認值。 ~~~ var [missing = true] = []; console.log(missing) // true var { x = 3 } = {}; console.log(x) // 3 ~~~ 它不僅可以用于數組,還可以用于對象。 ~~~ var { foo, bar } = { foo: "lorem", bar: "ipsum" }; foo // "lorem" bar // "ipsum" var o = { p1: [ "Hello", { p2: "World" } ] }; var { a: [p1, { p2 }] } = o; console.log(p1) // "Hello" console.log(p2) // "World" ~~~ 這種寫法的用途很多。 (1)交換變量的值。 ~~~ [x, y] = [y, x]; ~~~ (2)從函數返回多個值。 ~~~ function example() { return [1, 2, 3]; } var [a, b, c] = example(); ~~~ (3)函數參數的定義。 ~~~ function f({p1, p2, p3}) { // ... } ~~~ (4)函數參數的默認值。 ~~~ jQuery.ajax = function (url, { async = true, beforeSend = function () {}, cache = true, complete = function () {}, crossDomain = false, global = true, // ... more config }) { // ... do stuff }; ~~~ ## 數據結構 ### class結構 (1)基本用法 ES6提供了“類”(class)。此前,一般用構造函數模擬“類”。 ~~~ // ES5 var Language = function(config) { this.name = config.name; this.founder = config.founder; this.year = config.year; }; Language.prototype.summary = function() { return this.name+"由"+this.founder+"在"+this.year+"創造"; }; // ES6 class Language { constructor(name, founder, year) { this.name = name; this.founder = founder; this.year = year; } summary() { return this.name+"由"+this.founder+"在"+this.year+"創造"; } } ~~~ 在上面代碼中,ES6用constructor方法,代替ES5的構造函數。 (2)繼承 ES6的class結構還允許使用extends關鍵字,表示繼承。 ~~~ class MetaLanguage extends Language { constructor(x, y, z, version) { super(x, y, z); this.version = version; } summary() { //... super.summary(); } } ~~~ 上面代碼的super方法,表示調用父類的構造函數。 ### module定義 (1)基本用法 ES6允許定義模塊。也就是說,允許一個JavaScript腳本文件調用另一個腳本文件。 假設有一個circle.js,它是一個單獨模塊。 ~~~ // circle.js export function area(radius) { return Math.PI * radius * radius; } export function circumference(radius) { return 2 * Math.PI * radius; } ~~~ 然后,main.js引用這個模塊。 ~~~ // main.js import { area, circumference } from 'circle'; console.log("圓面積:" + area(4)); console.log("圓周長:" + circumference(14)); ~~~ 另一種寫法是整體加載circle.js。 ~~~ // main.js module circle from 'circle'; console.log("圓面積:" + circle.area(4)); console.log("圓周長:" + circle.circumference(14)); ~~~ (2)模塊的繼承 一個模塊也可以繼承另一個模塊。 ~~~ // circleplus.js export * from 'circle'; export var e = 2.71828182846; export default function(x) { return Math.exp(x); } ~~~ 加載上面的模塊。 ~~~ // main.js module math from "circleplus"; import exp from "circleplus"; console.log(exp(math.pi); ~~~ (3)模塊的默認方法 還可以為模塊定義默認方法。 ~~~ // circleplus.js export default function(x) { return Math.exp(x); } ~~~ ## ECMAScript 7 2013年3月,ECMAScript 6的草案封閉,不再接受新功能了。新的功能將被加入ECMAScript 7。根據JavaScript創造者Brendan Eich的[設想](http://wiki.ecmascript.org/doku.php?id=harmony:harmony),ECMAScript 7將使得JavaScript更適于開發復雜的應用程序和函數庫。 ECMAScript 7可能包括的功能有: * Object.observe:對象與網頁元素的雙向綁定,只要其中之一發生變化,就會自動反映在另一者上。 * Multi-Threading:多線程支持。目前,Intel和Mozilla有一個共同的研究項目RiverTrail,致力于讓JavaScript多線程運行。預計這個項目的研究成果會被納入ECMAScript標準。 * Traits:它將是“類”功能(class)的一個替代。通過它,不同的對象可以分享同樣的特性。 其他可能包括的功能還有:更精確的數值計算、改善的內存回收、增強的跨站點安全、類型化的更貼近硬件的(Typed, Low-level)操作、國際化支持(Internationalization Support)、更多的數據結構等等。 ## 參考鏈接 * Sayanee Basu,?[Use ECMAScript 6 Today](http://net.tutsplus.com/articles/news/ecmascript-6-today/) * Ariya Hidayat,?[Toward Modern Web Apps with ECMAScript 6](http://www.sencha.com/blog/toward-modern-web-apps-with-ecmascript-6/) * Nick Fitzgerald,?[Destructuring Assignment in ECMAScript 6](http://fitzgeraldnick.com/weblog/50/) * jmar777,?[What's the Big Deal with Generators?](http://devsmash.com/blog/whats-the-big-deal-with-generators) * Nicholas C. Zakas,?[Understanding ECMAScript 6 arrow functions](http://www.nczonline.net/blog/2013/09/10/understanding-ecmascript-6-arrow-functions/) * Dale Schouten,?[10 Ecmascript-6 tricks you can perform right now](http://html5hub.com/10-ecmascript-6-tricks-you-can-perform-right-now/) * Mozilla Developer Network,?[Iterators and generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators) * Steven Sanderson,?[Experiments with Koa and JavaScript Generators](http://blog.stevensanderson.com/2013/12/21/experiments-with-koa-and-javascript-generators/) * Matt Baker,?[Replacing callbacks with ES6 Generators](http://flippinawesome.org/2014/02/10/replacing-callbacks-with-es6-generators/) * Domenic Denicola,?[ES6: The Awesome Parts](http://www.slideshare.net/domenicdenicola/es6-the-awesome-parts) * Casper Beyer,?[ECMAScript 6 Features and Tools](http://caspervonb.github.io/2014/03/05/ecmascript6-features-and-tools.html) * Luke Hoban,?[ES6 features](https://github.com/lukehoban/es6features)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看