箭頭函數
ES6標準新增了一種新的函數:Arrow Function(箭頭函數)。
例如:
function(x){
return x * x;
}
用箭頭函數來表示:
x => x * x
箭頭函數相當於匿名函數,並且簡化了函數定義。箭頭函數有兩種格式
x => {
if (x > 0) {
return x * x;
}
else {
return - x * x;
}
}
如果參數不是一個,就需要用括號()括起來:
//兩個參數
(x,y) => x * x + y * y
//無參
(s) => 3.14
//可變參
(x,y,...rest) => {
var i,sum = x+ y;
for(i = 0;i<rest.length;i++){
sum += rest[i];
}
return sum;
}
如果要返回一個對象,就要注意,如果是單表達式,這麼寫的話會報錯:
//SyntaxError:
x => {foo:x}
因爲和函數體的{ … }有語法衝突,所以要改爲:
//正常
x = > ({foo:x)
this
箭頭函數 看上去是匿名函數的一種簡寫,但實際上,箭頭函數和匿名函數有個明顯的區別:箭頭函數內部的this是詞法作用域,由上下方文確定。
var boj = {
birth:1990,
getAge:function (){
var b = this.birth;//1990
var fn = function () {
return new Date.getFullYear() - this.birth;//
};
// var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
return fn();
}
};
console.log(boj.getAge());
會報錯誤:
修改爲:
var boj = {
birth:1990,
getAge:function (){
var b = this.birth;//1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
return fn();
}
};
console.log(boj.getAge());
如果使用了箭頭函數 ,以前的那種hack寫法:
var that = this;
就不需要 了。
generator
generator(生成器)是ES6標準引入的新的數據類型,一個generator看上去像一個函數,可以返回多次。
函數的定義
functoin foo(x){
return x + x;
}
var r = foo(1);//調用foo函數
函數在執行過程中,如果沒有遇到return語句(函數末尾如果沒有return ,就量隱含的return undefined;),控制權無法交回被調用的代碼。
function* foo(x){
yield x + 1;
yield x + 2;
return x + 3;
}
generator和函數不同的是,generator由function* 定義(注意多出的*),並且,除了return 語句,還可以用yield返回多次。
我們以一個著名的斐波那契數列爲例,它由0,1開頭:
0 1 1 2 3 5 8 13 21 34 ...
function* flb(max) {
var
t,
a = 0,
b = 1,
n = 0;
while(n < max){
yield a;
[a,b] = [b,a + b];
n ++;
}
return ;
}
// fib(5)僅僅是創建了一個generator對象,還沒有去執行它。
console.log(flb(5));
//第一種方式:不斷地調用generator對象的next()方法
var f = flb(5);
f.next(); // {value: 0, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 1, done: false}
f.next(); // {value: 2, done: false}
f.next(); // {value: 3, done: false}
f.next(); // {value: undefined, done: true}
//第二種方式:使用for..of遍歷
for (const x of flb(10)) {
console.log(x);
}
next()方法會執行generator的代碼,然後,每次遇到yield x;就返回一個對象{value:x,done:true/false},然後”暫停“。返回的value就是yiled的返回值,done表示這個generator是否已經執行結束了,如果done爲true,則value就是return 的返回值。
因爲generator可以在執行過程中多次返回,所以它看上去就像現代戰爭可以記住執行狀態的函數,利用這一點,寫一個generator就可以實現需要面向對象才能實現的功能。例如,用一個對象來保存狀態,得這麼寫:
var fib = {
a:0,
b:1,
n:0,
max:5,
next:function () {
var
r = this.a,
t = this.a + this.b;
this.a = this.b;
this.b = t;
if(this.n < this.max){
this.n ++;
return r;
}else{
return undefined;
}
}
}
generator還有另一個巨大的好處,就是把異步回調代碼變成“同步”代碼。這個好處要等到後面學了AJAX以後才能體會到。
沒有generator之前的黑暗時代,用AJAX時需要這麼寫代碼:
ajax('http://url-1', data1, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-2', data2, function (err, result) {
if (err) {
return handle(err);
}
ajax('http://url-3', data3, function (err, result) {
if (err) {
return handle(err);
}
return success(result);
});
});
});
用generator來寫
try {
r1 = yield ajax('http://url-1', data1);
r2 = yield ajax('http://url-2', data2);
r3 = yield ajax('http://url-3', data3);
success(r3);
}
catch (err) {
handle(err);
}