1. 程式人生 > >ES6 — 箭頭函式

ES6 — 箭頭函式

一 為什麼要有箭頭函式

我們在日常開發中,可能會需要寫類似下面的程式碼

  const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function () {
      setInterval(function () {
        console.log('我叫' + this.name + '我今年' + this.age + '歲!')
      }, 1000)
    }
  }
  Person.sayHello()

上例的輸出結果是什麼呢?可能對javascript特性不是很熟悉的同學(我自己也是)會認為輸出當然是
我叫little bear,今年18歲咯。如果你的答案是這個的話,那麼我要恭喜你,答錯了。其實上例的輸出結果是我叫undefined,今年我undefined歲。為什麼會輸出這種結果呢?
這是因為setInterval執行的時候,是在全域性作用域下的,所有this指向的是全域性window,而window上沒有name和age,所以當然輸出的是undefined咯。不明白的同學可以去看看this的工作原理

this
那麼,我們怎麼要解決這個問題呢?
通常的寫法是快取this,然後在setInterval中用快取的this進行操作,如下

 const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function () {
     let self = this
      setInterval(function () {
        console.log('我叫' + self.name + '我今年' + self.age + '歲!')
      }, 1000)
    }
  }
  const sayHelloFun = Person.sayHello
  sayHelloFun()

使用上敘方法,輸出的結果就是大家所期待的我叫little bear,我今年18歲了。
那麼,大家可能會覺得這樣不科學,明明是寫在物件裡面的方法,為什麼還要使用快取這個物件才能正確使用。ECMA組織覺得這確實是個問題,之後在es6的新特性裡添加了箭頭函式,它能很好的解決這個問題。另外箭頭函式還用簡化程式碼量的特點。

二 什麼是箭頭函式

箭頭函式的語法非常簡單,看一下最簡單的箭頭函式表示法
() => console.log('Hello')
之前沒有接觸過箭頭函式的人可能會驚訝於其程式碼的簡潔。對比之前如果要寫一個這樣的函式

function(){
console.log('hello')
}

箭頭函式的簡潔性一目瞭然。
更多關於箭頭函式語法可點選箭頭函式語法

三 和普通函式的區別

從上面的例子中,我們已經可以看出箭頭函式的優勢。
和普通函式相比,箭頭函式主要就是以下兩個方面的特點

  1. 不繫結this,arguments
  2. 更簡化的程式碼語法

第二個特點不需要過多贅述,下面我們來看看不繫結this和arguments這兩個特點

3.1 不繫結this

什麼叫不繫結this,我個人的理解為箭頭函式的this其實就是在定義的時候就確定好的,以後不管怎麼呼叫這個箭頭函式,箭頭函式的this始終為定義時的this
我們還是以前面的那個setInterval程式碼為例

const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function () {
      setInterval(function () {
        console.log('我叫' + this.name + '我今年' + this.age + '歲!')
      }, 1000)
    }
Person.sayHello()

當Person.sayHello()去執行setInterval的時候,是在全域性作用下執行的所有setInterval回撥函式的this就為全域性物件。es3-5中的函式this的值和呼叫這個函式的上下文有關。(注意是呼叫)
我們用箭頭函式重寫上訴函式

const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': () => {
      setInterval(() => {
        console.log('我叫' + this.name + '我今年' + this.age + '歲!')
      }, 1000)
    }
Person.sayHello()

大家猜猜結果是什麼???
輸出的是我叫’little bear’,今年18歲嘛?
哈哈,太天真了,我開始也是這樣想的,後面輸出之後發現結果不對,輸出的還是undefined。為什麼呢??
因為我把方法寫在了物件裡,而物件的括號是不能封閉作用域的。所以此時的this還是指向全域性物件。
所以,通過以上的錯誤可以提醒我們,最好不要用箭頭函式作為物件的方法。
我們需要重新舉一個例子,如下

function Person () {
  this.name = 'little bear',
  this.age = 18
  let self = this
  setInterval(function sayHello () {
    console.log('我叫' + self.name + '我今年' + self.age + '歲!')
  }, 1000)
}
let p = new Person()

快取this,然後輸出,能達到我們想要的結果。
把上述例子改為箭頭函式的形式如下

function Person () {
  this.name = 'little bear',
  this.age = 18
  setInterval(() => {
    console.log('我叫' + this.name + '我今年' + this.age + '歲')
},1000)
}
let p = new Person()

我們可以看到,箭頭函式使用了定義時上下文的this,且與在哪裡呼叫沒有關係。

3.2 不繫結arguments

箭頭函式還有一個比較有特點的地方就是其不繫結arguments,即如果你在箭頭函式中使用arguments引數不能得到想要的內容。

let arrowfunc = () => console.log(arguments.length)
arrowfunc()
//output 
arguments is not defined

所以在箭頭函式中我們是不能直接使用arguments物件的,但是如果我們又想獲得函式的引數怎麼辦呢?
我們可以使用剩餘引數來取代arguments剩餘引數詳情

let arrowfunc = (...theArgs) => console.log(theArgs.length)
arrowfunc(1,2)
//output
2

四 什麼時候不能用箭頭函式

前面我們已經看到了很多關於es6箭頭函式的好處,也看到了箭頭函式的一些不足。那麼我們應該在什麼時候使用箭頭函式,而什麼時候最好不要使用呢?
1.作為物件的方法
在寫這篇部落格的例子時,由於本人的水平確實有限,導致了篇頭出現的錯誤。不過我也想由此告訴大家,最好不要在物件的方法中使用箭頭函式,這樣可能會導致一些問題的產生。除非你很熟悉箭頭函式。
2.不能作為建構函式
由於箭頭函式的this不繫結的特點,所以不能使用箭頭函式作為建構函式,實際上如果這樣做了,也會報錯。
3.定義原型方法

function Person (name){
this.name = name
}
Person.prototype.sayHello = () => {
    console.log(this)
}
var p1 = new Person()
p1.sayHello()
//output 
window物件

這裡的this指向的是window物件,這點和在物件方法中定義有點像

五 總結

箭頭函式由於其程式碼的簡潔性和不繫結呼叫者this的特點,在非方法函式中使用是最合適的,而在方法函式中使用,需要特別注意它的this繫結問題,如果需要動態的修改this,最好還是不要使用箭頭函數了。所以永遠沒有一個解決方案能解決所有事情,只有合適的應用場景。

相關推薦

es6箭頭函式以及模板字串的拼接

es6箭頭函式:  //1.具有一個簡單引數的函式 var single=a=>a console.log(single('hello word')); //2.沒有引數的需要在箭頭前加上小括號 var logs=()=>{ console.log('這個是沒有

es6箭頭函式學習

1.具有一個簡單引數的函式 var single=a=>a console.log(single('hello word')); 2.沒有引數的需要在箭頭前加上小括號 var logs=()=>{ console.log('這個是沒有引數的函式'); } 3.多個引數需

js---ES6 箭頭函式的this指向

普通函式的this指向看的是: 1.呼叫者 2.有沒有call/apply改變this指向 3.new改變AO中的this為一個空的物件 4.什麼都沒有,單純呼叫函式,this就是window,在自己的AO中。 箭頭函式的this指向:箭頭函式在定義時執行器上下文的this的指向(不具有塊

ES6--箭頭函式建議

箭頭函式適合於無複雜邏輯或者無副作用的純函式場景下,例如用在map、reduce、filter的回撥函式定義中; 不要在最外層定義箭頭函式,因為在函式內部操作this會很容易汙染全域性作用域。最起碼在箭頭函式外部包一層普通函式,將this控制在可見的範圍內; 如開頭所述,箭頭函

ES6箭頭函式中的this繫結問題

關於this指向問題的討論一直是學習js不可忽視的重要部分,那些一個又一個圍繞this挖的筆試坑,彷彿永遠也填不完 var obj={ fn:function(){ console.log(this); } } obj.fn();//object  

ES6 箭頭函式 =>

定義一個巢狀的箭頭函式tmp1 let address = [ {first: '健康',last:'生活'} ]; const tmpl = addrs => ` <table> ${addrs.map(addr => `

ES6:箭頭函式

    作用: 定義匿名函式     基本語法:          沒有引數: () => console.log('xxx')         一個引數: (i) => i+2         大於一個引數: (i,j) => i+j         函式

es6箭頭函式中return的用法

最近在專案中頻繁的使用了箭頭函式,在使用的過程中對return關鍵字用法比較困惑,下面對其使用方法進行記錄: 如果箭頭函式的程式碼塊部分多於一條語句,就要使用大括號將它們括起來,並且使用return關鍵字返回 例子: const foo = (a, b) =

解析ES6箭頭函式中的this

ES6中新增了箭頭函式這種語法,箭頭函式以其簡潔性和方便獲取this的特性,接下來通過本文給大家分享ES6箭頭函式中的this,寫的十分的全面細緻,具有一定的參考價值,對此有需要的朋友可以參考學習下。如有不足之處,歡迎批評指正。 簡要介紹:箭頭函式中的this,指向與一般fun

從一道面試題看ES6箭頭函式

前幾天頭條面試碰到了這樣一道面試題,讓我寫出每行程式碼的執行結果: var f = x => x; f(1); //return 1 var f = x => {x}; f(1); //function(x)={x}; var f = x =

es6 箭頭函式的this 指向問題

箭頭函式體內的this,就是定義時,函式所在的物件,而不是呼叫時所在的物件。 var foo = () => { console.log(this.id); } var id = 1; foo(); // 輸出1 // this 的指向一直是指向 window foo.call(

ES6箭頭函式基本用法

ES6箭頭函式基本用法 ``` window.onload = function(){ alert(abc); } //箭頭函式 window.onload = ()=>{ alert("abc"); } // 如果只有一個引數圓括號可以省 let play = function(num){ ale

【ECMAScript 5_6_7】6、ES6——箭頭函式

一、箭頭函式 * 作用: 定義匿名函式 * 基本語法: * 沒有引數: () => console.log('xxxx') * 一個引數: i => i+2 * 大於一個引數: (i,j) => i+j * 函式體不用大括號: 預設返回結果 * 函

深入理解ES6箭頭函式的this以及各類this面試題總結

ES6中新增了箭頭函式這種語法,箭頭函式以其簡潔性和方便獲取this的特性,俘獲了大批粉絲兒它也可能是面試中的寵兒, 我們關鍵要搞清楚 箭頭函式和普通函式中的this一針見血式總結:普通函式中的this:1. this總是代表它的直接呼叫者(js的this是執行上下文), 例

ES6 箭頭函式 柯里化

先來看下高階函式定義: 接受1個或多個函式作為引數返回函式型別 常規ES6箭頭函式用法:(返回值型別)const square = x => x * x;高階寫法: const has = p => o => o.hasOwnProperty(p);co

ES6箭頭函式修復ES5中this指向問題

長期以來,ES5中this物件一直的指向一個令人頭痛的問題,在物件方法中使用此,必須非常小心例如: class Animal { constructor(){ this.type = 'animal' } says(say){ setTim

ES6箭頭函式

一 為什麼要有箭頭函式 我們在日常開發中,可能會需要寫類似下面的程式碼 const Person = { 'name': 'little bear', 'age': 18, 'sayHello': function () {

ECMAScript 6 學習系列課程 (ES6 箭頭函式的使用)

在ES6語法中,簡化了對函式的書寫,其實,最初並不適應這樣的寫法,感覺很奇怪,但是永久了,發現這種方式更加直觀,如果有了解swift語法的一定對箭頭函式不陌生。 下面我們來看一下這個箭頭函式在ES6中是如何應用的: odds = evens.map(v

ES6箭頭函式(Arrow Functions)

ES6可以使用“箭頭”(=>)定義函式,注意是函式,不要使用這種方式定義類(構造器)。 一、語法 1. 具有一個引數的簡單函式 1 2 var single = a => a single('hello, world'

ES6 箭頭函式中的 this?(臨時性儲存)

是否區域性(Lexical)? 包括我在內的許多人,都會這麼描述箭頭函式裡 this 的行為:區域性的 this。什麼意思呢? <body> <div id="demo" onclick="foo()" > 點我</div&