函數定義可使用「function」關鍵字,代碼函數頭和函數體組成,函數頭能夠由函數名和參數列表組成,語法格式:函數名(參數列表){函數體}。如bash
function name(arg){console.log(arg)}
複製代碼
調用app
name(arg)
複製代碼
當函數沒有函數名的時候稱匿名函數函數
function(arg){console.log(arg)}
複製代碼
一般須要賦值給一個變量,否則報錯ui
var name=function(arg) {
console.log(arg)
}
複製代碼
調用this
name(arg)
複製代碼
定義在對象裏spa
var obj={
fn:function name() {
console.log(name.name+" "+name.length)
}
}
複製代碼
能夠這樣調用rest
obj.fn()
複製代碼
還用一種就是定義完就立刻被調用code
(function name() {
console.log(name.name+" "+name.length)
})();
複製代碼
這裏只列了經常使用的函數聲明及調用方式對象
ES6標準新增了一種新的函數:Arrow Function(箭頭函數)。ip
爲何叫Arrow Function?由於它的定義用的就是一個箭頭:
x => x * x
複製代碼
上面的箭頭函數至關於:
function (x) {
return x * x;
}
複製代碼
箭頭函數至關於匿名函數,而且簡化了函數定義。箭頭函數有兩種格式,一種像上面的,只包含一個表達式,連{ ... }和return都省略掉了。還有一種能夠包含多條語句,這時候就不能省略{ ... }和return:
x => {
if (x > 0) {
return x * x;
}
else {
return - x * x;
}
}
若是參數不是一個,就須要用括號()括起來:
// 兩個參數:
(x, y) => x * x + y * y
// 無參數:
() => 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 }
由於和函數體的{ ... }有語法衝突,因此要改成:
// ok:
x => ({ foo: x })
this
複製代碼
箭頭函數看上去是匿名函數的一種簡寫,但實際上,箭頭函數和匿名函數有個明顯的區別:箭頭函數內部的this是詞法做用域,由上下文肯定。
回顧前面的例子,因爲JavaScript函數對this綁定的錯誤處理,下面的例子沒法獲得預期結果:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = function () {
return new Date().getFullYear() - this.birth; // this指向window或undefined
};
return fn();
}
};
複製代碼
如今,箭頭函數徹底修復了this的指向,this老是指向詞法做用域,也就是外層調用者obj:
var obj = {
birth: 1990,
getAge: function () {
var b = this.birth; // 1990
var fn = () => new Date().getFullYear() - this.birth; // this指向obj對象
return fn();
}
};
obj.getAge(); // 25
複製代碼
若是使用箭頭函數,之前的那種hack寫法:
var that = this;
複製代碼
就再也不須要了。
因爲this在箭頭函數中已經按照詞法做用域綁定了,因此,用call()或者apply()調用箭頭函數時,沒法對this進行綁定,即傳入的第一個參數被忽略:
var obj = {
birth: 1990,
getAge: function (year) {
var b = this.birth; // 1990
var fn = (y) => y - this.birth; // this.birth還是1990
return fn.call({birth:2000}, year);
}
};
obj.getAge(2015); // 25
複製代碼