ES6允許使用箭頭(=>)定義函數
var f = v => v;
//等同于
var f = function(v){
return v;
}
如果箭頭函數不需要參數或需要多個參數,就使用一個圓括号代表參數部分。
var f = () => 5;
console.log(f());
//相當于
var f = function(){
return 5;
}
var sum = (num1,num2) => num1 + num2;
console.log(sum(1,2));
//相當于
var sum = function(sum1,sum2){
return sum1 + sum2;
}
如果箭頭函數的代碼塊部分多于一條語句,就要使用大括号将它們括起來,并且可以使用return 傳回語句。
var f = () => {
var a = 1;
var b = 2;
return a + b;
}
console.log(f());
由于大括号被解釋為代碼塊,是以如果箭頭函數直接傳回的一個對象,必須在對象外面加上大括号,否則會報錯。
let func = id => { id : id, name : 'Temp'} //報錯
let func = id => ({ id : id , name : 'wng'});
上面代碼中,原始意圖是傳回一個對象{a : 1},但是由于引擎認為大括号是代碼塊,是以執行了一行語句 a : 1 。這是,a可以被解釋為語句的标簽,是以實際執行的語句是1,然後函數就結束了,沒有傳回值。
如果箭頭函數隻有一行語句,且不需要傳回值,可以采用下面的寫法,就不用寫大括号了。
let fu = () => 1 + 2;
let fn = () => void fu();
console.log(fn());
箭頭函數可以與變量解構指派結合使用。
const full = ({first,last}) => first + " " +last;
console.log(full({first : 1, last : 2}));
箭頭函數的一個用處是可以簡化回調函數。
let arr2 = arr.map((x) => x = x + 1);
rest參數結合箭頭函數。
const number = (...values) => values;
console.log(number(1,2,3,4,5,6,7,8,9));
const fun = (first,...last) => [first,last];
console.log(fun(1,2,3,4,5,6));
箭頭函數的注意點
1.函數體内的this對象,就是定義時所在的對象,而不是使用時所在的對象。
2.不可以當做構造函數,也就是說不可以使用new指令,否則會抛出一個錯誤
3.不可以使用arguments對象,該對象在函數體内不存在。如果要用,可以使用rest參數。
4.不可以使用yield指令,是以箭頭函數不能用作Generator函數
第一點注意:this對象的指向是可變的,但是,在箭頭函數中,它是固定不變的
var obj = {
fun : function(){
setTimeout(function(){
console.log(this);
},1000)
}
}
obj.fun(); //window
var obj1 = {
fun : function(){
setTimeout(() =>{
console.log(this);
},1000);
}
}
obj1.fun();
var obj2 = {
num : 123,
fun : function(){
console.log(this);
var f = () => {
console.log(this);
}
f();
setTimeout(() => {
console.log(this.num);
},1000);
}
}
obj2.fun()
//自己可以運作一下
箭頭函數可以讓this指向固定化,這種特性很有利于封裝回調函數。但是,this指向的固定化,并不是因為箭頭函數内部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this,導緻内部的this就是外層代碼塊的this。正式因為它沒有this,是以也就不能用作構造函數。
箭頭函數轉成ES5的代碼如下
function foo(){ //ES6
setTimeout( () => {
console.log('id:',this.id);
},100);
}
//ES5
function foo(){
var _this = this;
setTimeout( () => {
console.log("id :" , _this.id);
})
}
除了this,以下三個變量在箭頭函數之中也是不存在的,指向外層函數的對應變量:arguments,super,new.target。
function foo(){
setTimeout( () => {
console.log(arguments); //callee :foo
},100);
}
foo(2,4,6,8);
//上面代碼中,箭頭函數内部的變量arguments,其實是函數foo的arguments變量
另外,由于箭頭函數沒有自己的this,是以當然也不能用call(),apply(),bind()這些方法去改變this的指向。
(function(){
return [
(() => this.x).bind({x : 'inner'})()
]
}).call({x : 'outer'});
//箭頭函數沒有自己的this,是以bind方法無效,内部的this指向外部的this
嵌套的的箭頭函數:箭頭函數内部,還可以再使用箭頭函數。
function insert(value) {
return {
init : function (array){
return {
after : function(afterValue) {
array.splice(array.indexOf(afterValue) + 1,0,value);
return array;
}
}
}
}
}
console.log(insert(2).init([1,3]).after(1));
let insert = (value) => ({init : (array) => ({after : (afterValue) => {
array.splice(array.indexOf(afterValue) + 1 , 0 , value);
return array;
/ }})});
console.log(insert(2).init([1,3]).after(1));
部署管道機制:下面reduce方法中的b方法把a方法作為參數傳過去,這個我也不了解這個執行過程。
const pipeline = (...funcs) => val => funcs.reduce((a,b) => b(a),val);
const plus1 = a => a + 1;
const mult2 = a => a * 2;
const addThenMult = pipeline(plus1,mult2);
console.log(addThenMult(5));
在别的地方看到别人寫的ES5的形式,也就是addThenMult這個方法。
const addThenMult = function(num){
return pipeline(plus1(num),mult2)
}
//這裡在plus1那裡把參數傳了進去,我也不懂這個地方
首頁傳送門