這是ES6 In Depth的閱讀筆記,只記錄程式的範例方便語法的查詢,但我強列推薦去讀讀這系列的原始文章,它對於ES6的語法有很深入的介紹,非常值得一讀。
for (var index = 0; index < myArray.length; index++) {
console.log(myArray[index]);
}
缺點:要先知道array的大小。
myArray.forEach(function (value) {
console.log(value);
});
缺點:無法使用break與return。
for (var index in myArray) { // don't actually do this
console.log(myArray[index]);
}
缺點:1. index的值不是integer,而是string。2. for in不只會跑過array裡的element,連動態加入屬性(expando properties)的值也會一起跑。3. 在某些情況下,for in不會照array的順序,而是照element的文字排序進行迴圈。簡言之,for in當初只是為了object而設計的,不適合用在array中。
for (var value of myArray) {
console.log(value);
}
for of 基本上解決了上面迴圈遇到的問題,帶來了下面的優點:
for (var [key, value] of phoneBookMap) {
console.log(key + "'s phone number is: " + value);
}
for (var key of Object.keys(someObject)) {
console.log(key + ": " + someObject[key]);
}
var zeroesForeverIterator = {
[Symbol.iterator]: function () {
return this;
},
next: function () {
return {done: false, value: 0};
}
};
Generator function即是具有暫停功能的function。
function* quips(name) {
yield "hello " + name + "!";
yield "i hope you are enjoying the blog posts";
if (name.startsWith("X")) {
yield "it's cool how your name starts with X, " + name;
}
yield "see you later!";
}
其中要使用 function* 宣告generator function,而 yield 就是類似 return,也就是每次呼叫 next 暫停回傳的值。
> var iter = quips("jorendorff");
[object Generator]
> iter.next()
{ value: "hello jorendorff!", done: false }
> iter.next()
{ value: "i hope you are enjoying the blog posts", done: false }
> iter.next()
{ value: "see you later!", done: false }
> iter.next()
{ value: undefined, done: true }
範例:實作一個function傳入start與end,回傳一個iterator。
class RangeIterator {
constructor(start, stop) {
this.value = start;
this.stop = stop;
}
[Symbol.iterator]() { return this; }
next() {
var value = this.value;
if (value < this.stop) {
this.value++;
return {done: false, value: value};
} else {
return {done: true, value: undefined};
}
}
}
function range(start, stop) {
return new RangeIterator(start, stop);
}
上面的程式碼可以用generator簡化成:
function* range(start, stop) {
for (var i = start; i < stop; i++)
yield i;
}
常用的情境:
Generator的另一個用處是將async的function,轉成用一般function(也就是sync)的方式撰寫,但實際上它仍是async的執行方式。下面是範例:
// Synchronous code to make some noise.
function makeNoise() {
shake();
rattle();
roll();
}
// Asynchronous code to make some noise.
// Returns a Promise object that becomes resolved
// when we're done making noise.
function makeNoise_async() {
return Q.async(function* () {
yield shake_async();
yield rattle_async();
yield roll_async();
});
}
template string即是可以在字串中帶入變數顯示,這類的字串會用`
這個符號來定義字串,如下所示:
`User ${user.name} is not authorized to do ${action}.`
它有下面的特性:
.toString()
這個method。`
,則需要用\
做跳脫字元。例如:`\``
。${
,則同樣也要做跳脫字元,可以選其中一個做即可,例如:\${
或是\$\{
。$("#warning").html(`
Watch out!
Unauthorized hockeying can result in penalties
of up to ${maxPenalty} minutes.
`);
var message = SaferHTML`${bonk.sender} has sent you a bonk.`;
function SaferHTML(templateData) {
var s = templateData[0];
for (var i = 1; i < arguments.length; i++) {
var arg = String(arguments[i]);
s += arg.replace(/&/g, "&")
.replace(//g, ">");
s += templateData[i];
}
return s;
}
i18n`Hello ${name}, you have ${amount}:c(CAD) in your bank account.`
// => Hallo Bob, Sie haben 1.234,56 $CA auf Ihrem Bankkonto.
``
來呈現程式碼,例如:To display a message, write ``alert(`hello world!`)``.
如果要在函式中處理不定個數參數的傳入,在ES6之前的作法是使用arguments
這個內建變數,範例如下:
containsAll("banana", "b", "nan")
function containsAll(haystack) {
for (var i = 1; i < arguments.length; i++) {
var needle = arguments[i];
if (haystack.indexOf(needle) === -1) {
return false;
}
}
return true;
}
其中 haystack 的值即為 "banana",而 arguments 的值為 ["banana", "b", "nan"]。這樣的處理方式有幾個缺點:
ES6有了 rest arguements 可以改寫成下面這個樣子:
function containsAll(haystack, ...needles) {
for (var needle of needles) {
if (haystack.indexOf(needle) === -1) {
return false;
}
}
return true;
}
其中 haystack 的值即為 "banana",而 needles 的值為 ["b", "nan"]。使用 rest arguments 要注意的是:
在ES6中允許函式的參數列可以設定預設值,如下所示:
function animalSentence(animals2="tigers", animals3="bears") {
return `Lions and ${animals2} and ${animals3}! Oh my!`;
}
當參數沒有傳入時,就會使用設定的預設值當做傳入的參數。使用 default parameters 要注意的是:
function animalSentenceFancy(animals2="tigers", animals3=(animals2 == "bears") ? "sealions" : "bears") {
return `Lions and ${animals2} and ${animals3}! Oh my!`;
}
function myFunc(a=42, b) {...}
相當於function myFunc(a=42, b=undefined) {...}