箭頭函數(Arrow Functions) 就像名字所說那樣,箭頭函數使用箭頭(=>)來定義函數。與傳統函數相比,箭頭函數在多個地方表現不一樣。 箭頭函數語法(Arrow Function Syntax) 箭頭函數有多種實現方法。比如你想實現一個只有一個參數並且直接返回此參數值的函數: 上面的例子中 ...
箭頭函數(Arrow Functions)
就像名字所說那樣,箭頭函數使用箭頭(=>)來定義函數。與傳統函數相比,箭頭函數在多個地方表現不一樣。
箭頭函數語法(Arrow Function Syntax)
箭頭函數有多種實現方法。比如你想實現一個只有一個參數並且直接返回此參數值的函數:
let reflect = value => value; //相當於下麵的函數 let reflect = function(value) { return value; };
上面的例子中,函數只有一個參數,所以用不用()都是可以的。如果你的參數包含多個,就需要用()包住參數了:
let sum = (num1, num2) => num1 + num2; //相當於下麵的函數 let sum = function(num1, num2) { return num1 + num2; };
另外如果函數沒有參數,()也是必須的:
let getName = () => "Zakas"; //相當於下麵的函數 let getName = function() { return "Zakas"; };
如果函數體內包含多個表達式,那麼就需要用{}包圍住函數體了:
let sum = (num1, num2) => { num1 = num1 + 3; return num1 + num2; }; //相當於下麵的函數 let sum = function(num1, num2) { num1 = num1 + 3; return num1 + num2; };
其實可以看到,箭頭函數可以直接按照(參數)=> {函數體}的方式來寫就可以了。上面的例子只是為了說箭頭函數在某些情況下可以簡寫。
那麼除了語法外,箭頭函數與傳統函數相比,有哪些不一樣呢?
1、沒有this、super、argument和new.target綁定
this、super、argument和new.target的值由最內層包含箭頭函數的非箭頭函數決定。首先來看arugments綁定:
function outer(num1, num2) { return function () { return arguments[0]; } } let inner = outer(1, 2); console.log(inner(3)); // 3 ---------------------------------------------------------- function outer(num1, num2) { return () => { return arguments[0]; } } let inner = outer(1, 2); console.log(inner(3)); // 1
箭頭函數本身沒有arguments對象,實際上訪問的是外層的outer函數的arguments對象,所以輸出1。 不過在箭頭函數中可以使用剩餘參數訪問函數的參數。
在JavaScript中,this綁定是一個比較複雜的機制,因為this具體指向的值要到實際執行時才能決定,並不一定是定義時所指向的值。在箭頭函數中沒有this綁定,其實就是指this的值在函數定義時就已經確定了,並不會在實際執行時改變值。來看一個例子:
function foo() { return () => { return this.a; } } var obj1 = {a: 2}; var obj2 = {a: 3}; var bar = foo.call(obj1); console.log(bar.call(obj2)); // 2
上面的代碼中,bar在創建時,this被綁定到obj1上,然後在執行時,this的值不會被重新綁定到obj2,因此輸出2。如果裡面的函數是傳統函數,那麼輸出3。
new.target和super都是ES6引入的標準,在後面會進行說明。
2、沒有prototype,不能被new調用
let foo = () => {}; console.log(foo.prototype); // undefined let obj = new foo(); // TypeError: foo is not a constructor
3、不允許重覆命名的參數
不管是strict模式還是not-strict模式,箭頭函數都不允許重覆命名的參數:
let sum = (num1, num2, num1) => { // SyntaxError: Duplicate parameter name not allowed in this context num1 = num1 + 3; return num1 + num2; };