ES6學習筆記 箭頭函數 箭頭函數一直在用,最近突然想到重新看一下箭頭函數的用法,所以這裡做一些總結. 箭頭函數長這個樣子: 這個函數就類似於: 上面的實例就是一個參數的情況,當然也可以沒有參數,或者有多個參數 沒有參數 兩個及以上參數 { } js let fn = (a, b) = { a + ...
ES6學習筆記--箭頭函數
箭頭函數一直在用,最近突然想到重新看一下箭頭函數的用法,所以這裡做一些總結.
箭頭函數長這個樣子:
let fn = a => a++; // fn 是函數名, a=>a*a 是函數體
這個函數就類似於:
let fn = function (a) {
return a++;
}
上面的實例就是一個參數的情況,當然也可以沒有參數,或者有多個參數
沒有參數
// 示例1
let fn = () => 2 + 3;
// 相當於
let fn = function() {
return 2 + 3;
}
//=========我是分割線===========
// 示例2
let fn1 = () => console.log('Hello World!');
// 相當於
let fn1 = function() {
console.log('Hello World!');
}
兩個及以上參數
// 示例1
let fn1 = (a, b) => a + b;
// 相當於
let fn1 = function(a, b) {
return a + b;
};
//=========我是分割線===========
// 示例2
let fn2 = (a, b, ...rest) => {
let i, sum = a + b;
for( i = 0; i < rest.length; i++ ){
sum += rest[i];
}
return sum;
}
// 相當於
let fn2 = function(a, b,...rest) {
let i, sum = a + b;
for( i = 0; i < rest.length; i++ ){
sum += rest[i];
}
return sum;
}
說明: 上面的示例2,因為箭頭右側的函數代碼塊不止一條語句,所以要使用
{ }
(大括弧) 包起來,如果需要接收函數的執行結果,則需使用 return 返回,比如下麵的情況
let fn = (a, b) => { a + b };
控制台輸出:
沒有 return ,所有沒有返回值
一種特殊情況
由於大括弧會被解釋為代碼塊,所以在使用箭頭函數時,如果要返回一個對象,則 必須
把這個對象用 ()
包裹起來.
// 錯誤代碼
let fn1 = (a, b) => {
name: a,
age: b
}
console.log(fn1('Jack', 20));
這個是會報錯的,正確的應該這樣
// 正確的寫法
let fn1 = (a, b) => (
{
name: a,
age: b
}
)
箭頭函數可以與變數結構結合使用
let personInfo = {
firstname: 'chen',
lastname: 'huigong'
}
let person = ({ firstname, lastname }) => firstname + ' ' + lastname;
console.log(person(personInfo));
// 相當於
let person = function(person) {
return person.firstname + ' ' + person.lastname;
}
console.log(personInfo);
一些註意點
箭頭函數在使用的時候有一些註意點.
- 函數體內的 this 對象, 指的是定義時的對象,而不是使用時所在的對象
箭頭函數看上去是匿名函數的簡寫,但是箭頭函數和匿名函數有一個特別明顯的區別: 箭頭函數內部的 this 是詞法作用域,由上下文確定,看下麵的代碼
let person = {
birthday: 1990,
getAge: function() {
let b = this.birthday; // 1990
let fn = function() {
return new Date().getFullYear() - this.birthday; // this 現在指向 window 或 undefined
};
return fn();
}
}
person.getAge(); // NaN
此時,由於fn
裡面的 this 不指向 person 自身,所以執行 person.getAge()
就會出現問題
使用箭頭函數就解決了這個問題
let person = {
birthday: 1990,
getAge: function() {
let b = this.birthday; // 1990
let fn = () => new Date().getFullYear() - this.birthday; // this 指向 person 對象
return fn();
}
}
person.getAge(); // 27
使用了箭頭函數,則以前的 hack 寫法就不需要了
let _this = this;
this
指向的固定化,並不是因為箭頭函數內部有綁定this的機制,實際原因是箭頭函數根本沒有自己的this
,導致內部的this就是外層代碼塊
的this.正是因為它沒有this,所以也就不能用作構造函數
.
箭頭函數是不可以當做
構造函數
的,也就是說,不可以使用new
命令,否則會拋出錯誤.不可以使用
arguments
對象,該對象在函數體內是不存在的.如果要使用,可以用rest
參數代替.不可以使用
yield
命令,因此箭頭函數不能用作Generator
函數.
其他的一些問題
除了this,以下三個變數在箭頭函數中也是不存在的,指向外層函數的對應變數: arguments
, super
, new.target
.
function foo() {
setTimeout(() => {
console.log('args:', arguments);
}, 100 )
}
foo(2, 4, 6, 8); // args: [2, 4, 6, 8]
上面代碼中,箭頭函數內部的變數
arguments
,其實是函數foo
的arguments
變數.另外,由於箭頭函數沒有自己的this
,所以當然也就不能用call()
、apply()
、bind()
這些方法去改變this的指向.