概述
java現在都支援lambda表達式,js怎麼能示弱呢?來來(arrow function)箭頭函數走起,跟着大哥有肉吃,哈哈,剛開始學習javaScript,每個人都會想這小哥和java什麼關系?關系不大就是有點像。對對跑偏了,言歸正傳,箭頭函數是一般的函數的簡寫,簡寫就是圖個友善,圖友善是要付出代價,它是不能綁定它的this(本對象),arguments(參數對象),super(沒有父構造方法)或者new.target(新的目标),箭頭函數這麼多東西被砍掉了,它非常适合無方法名的函數,它不能用作構造器。
1.文法
基本文法:
//表達式(參數1,參數2,..., paramN) => {表達式}
(param1, param2, …, paramN) => { statements };
(param1, param2, …, paramN) => expression
//等同于: (param1, param2, …, paramN) => { return expression; }
// 當中有一個參數的時候可以省略括号()
(singleParam) => { statements }
singleParam => { statements }
// 對于無參的也應該加上()括号,保證格式完整性
() => { statements }
進階文法:
// 圓括号(json格式對象) ,不能去掉圓括号
params => ({foo: bar})
//支援rest 參數 和預設值
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
//支援解構,簡單就是給個規則一一對應
let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f();
// 6
2.簡化過程:
var f = [1,2,4,5,6]
//js标準寫法
var first = f.map(function(element){
return element*2;
});
//簡化function
var second= f.map((element)=>{
return element*2;
});
//簡化函數體
var third = f.map((element)=>element*2);
console.log(second);//[2, 4, 8, 10, 12]
3.不綁定this
除了箭頭函數,每個新的函數都有他自己的this值,(相當于一個對象的構造方法),這樣上下文函數被稱為對象方法,這是非常惱火的面向對象程式設計方式。
function Person() {
// this就是類似java的本對象,就是該類自己執行個體化的對象
this.age = 0;
setInterval(function growUp() {
//growUp自己也有this對象,是以這裡this和Person的this是不一樣的
this.age++;
}, 1000);
}
var p = new Person();
在ECMAScript 3/5,被靈活指派到一個變量替代本對象,這種方式會被淘汰
function Person() {
var that = this;
that.age = 0;
setInterval(function growUp() {
//that就是Person()的this對象
that.age++;
}, 1000);
}
箭頭函數發揮作用的時候到了,就是它沒有綁定自己的this。
function Person(){
this.age = 0;
setInterval(() => {
this.age++; // |this| 就是引用person的this對象
}, 1000);
}
var p = new Person();
通過Call 或者apply調用 ,它隻是通過參數,this将會被忽略
var adder = {
base: 1,
add: function(a) {
var f = v => v + this.base;
return f(a);
},
addThruCall: function(a) {
var f = v => v + this.base;
var f1 = (function(v) {
return v+this.base;
});
var b = {
base: 2
};
return f1.call(b, a);
}
};
console.log(adder.add(1)); // 列印日志2
console.log(adder.addThruCall(1)); //f箭頭函數列印日志2 ,f1普通函數列印日志為3(普通函數綁定this,這是就是b對象,b.base=2)
4.不綁定arguments參數對象
//這是簡單變量名,當然不是嚴格模式下,嚴格模式下會報錯
var arguments = 42;
var arr = () => arguments;
arr(); // 42
function foo() {
var f = (i) => arguments[0] + i; // 這個arguments[0]隐性綁定了1
return f(2);
}
foo(1); // 3
console.log(foo(1));
但是如果我想要傳遞變量怎麼辦,這時候可以有rest 參數進行傳遞
function foo(i){
var f = (...args)=>args[0]+args[1];
return f(2,i);
}
console.log(foo(12))//結果14
5.箭頭函數的例子
'use strict';
//隻要{} 裡面就是鍵值對,值可以普通,也可是函數
var obj = {
i: 10,
b: () => console.log(this.i, this),
c: function() {
console.log(this.i, this);
}
}
obj.b(); // prints undefined, Object {...}
obj.c(); // prints 10, Object {...}
6.箭頭函數不能new,因為它沒有綁定構造函數
var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor ,抛出異常
7.箭頭函數不能使用(prototype)原生屬性
var Foo = () => {};
console.log(Foo.prototype); // undefined
8.對于箭頭函數的主體如果是單一,不用寫return,如果是塊語句必須用return(也就是用{}包裹的語句)
var func = x => x * x;
//自動會給你添加return
var func = (x, y) => { return x + y; };
//這個必須自己寫個return var f=()=>{return {bb:12}};
console.log(f());
9.傳回json格式的對象字元串
var func = () => { foo: 1 };
// Calling func() returns undefined!(未定義)
var func = () => { foo: function() {} };
// SyntaxError: function statement requires a name 文法錯誤
//因為{foo:function(){}}當做一條語句執行,而不是對象中鍵值對。
//改進一下
var func= ()=> {return ({foo:function(){}})}
10.不允許箭頭函數在=>位置錯行
var func = ()
=> 1;
// SyntaxError: expected expression, got '=>'
11.箭頭的函數解析規則
let callback;
callback = callback || function() {}; // 這樣寫沒毛病
callback = callback || () => {};
// SyntaxError: invalid arrow-function arguments 報錯 ()=>{}不是一個整體
callback = callback || (() => {}); // 這樣寫也沒問題
12.更多例子:
// empty傳回undefined
let empty = () => {};
(() => 'foobar')();
// Returns "foobar"
// (this is an Immediately Invoked Function Expression
// see 'IIFE' in glossary)
var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10
let max = (a, b) => a > b ? a : b;
// Easy array filtering, mapping, ...
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b);
// 66
//過濾偶數
var even = arr.filter(v => v % 2 == 0);
// [6, 0, 18]
var double = arr.map(v => v * 2);
// [10, 12, 26, 0, 2, 36, 46]
// More concise promise chains
promise.then(a => {
// ...
}).then(b => {
// ...
});
// Parameterless arrow functions that are visually easier to parse
setTimeout( () => {
console.log('I happen sooner');
setTimeout( () => {
// deeper code
console.log('I happen later');
}, 1);
}, 1);