ECMAScript 6 語法學(xué)習(xí)——箭頭函數(shù)

概述

在ECMAScript 6中允許使用箭頭(=>)定義函數(shù)洒擦。箭頭函數(shù)的語法多變论熙,根據(jù)實(shí)際的使用場景有多種形式

箭頭函數(shù)的語法

單一參數(shù)梦皮、函數(shù)體只有一條語句的箭頭函數(shù)定義如下

let welcome = msg => msg
/*
相當(dāng)于
function welcome(msg) {
    return msg
}
*/

console.log(welcome("welcome you."))

如果一個(gè)函數(shù)有多個(gè)參數(shù)芹缔,則需要使用圓括號

let welcome = (user, msg) => `${user}, ${msg}`
/*
相當(dāng)于
function welcome(user, msg) {
    return user + ", " + msg
}
*/

console.log(welcome("John", "welcome you."))

如果函數(shù)沒有參數(shù)驾孔,則需要使用一對空的圓括號表示

let welcome = () => "welcome you."
/*
相當(dāng)于
function welcome() {
    return "welcome you."
}
*/

console.log(welcome())

如果函數(shù)體有多條語句秋度,則需要使用花括號包裹函數(shù)體

let add = (a, b) => {
    let c = a + b
    return c
}
/*
相當(dāng)于
function add(a, b) {
    let c = a + b
    return c
}
*/

console.log(add(4, 6))

如果要創(chuàng)建一個(gè)空函數(shù)炸庞,則需要使用一對圓括號來表示參數(shù)內(nèi)容并且使用一對花括號表示函數(shù)體部分

let emptyFunction = () => {}
/*
相當(dāng)于
function emptyFunction() {}
*/

如果箭頭函數(shù)的返回值是一個(gè)對象字面量,則需要將該字面量包裹在圓括號中

let createCar = (color, doors) => ({color : color, doors : doors})
/*
相當(dāng)于
function createCar(color, doors) {
    return {
        color : color,
        doors : doors
    }
}
*/

console.log(createCar("black", 4))
  • 將對象字面量包裹在圓括號中是為了將其與函數(shù)體區(qū)分開

箭頭函數(shù)可以和對象解構(gòu)結(jié)合使用

let personInfo = ({name, age}) => `${name}'s age is ${age} years old.`
/*
相當(dāng)于
function personInfo({name, age}) {
    return `${name}'s age is ${age} years old.`
}
*/

let person = {
    name : John,
    age : 18
}
console.log(personInfo(person))

箭頭函數(shù)與this

JavaScript中的this關(guān)鍵字與其他高級語言中的this引用或this指針不同荚斯,JavaScript中的this并不是指向?qū)ο蟊旧聿壕樱渲赶蚴强梢愿淖兊模鶕?jù)當(dāng)前執(zhí)行上下文的變化而改變事期。

代碼示例

<!DOCTYPE html>
<html>
    <head>
        <script>
            var greeting = "Welcome"
            function sayHello(user) {
                alert(this.greeting + ", " + user)
            }

            var obj = {
                greeting : "Hello",
                sayHello : sayHello
            }

            // Welcome, John
            sayHello("John")
            // Hello, John
            obj.sayHello("John")
            var sayHi = obj.sayHello
            // Welcome, John
            sayHi("John")
        </script>
    </head>
</html>

下面來分析下上述代碼

  1. 調(diào)用sayHello("John")時(shí)滥壕,相當(dāng)于執(zhí)行window.sayHello("John"),因此函數(shù)內(nèi)部的this指向的是window對象兽泣,我們在代碼第一行定義的全局變量greeting將自動成為window對象的屬性绎橘,因此最后的結(jié)果是“Welcome, John”。
  2. 調(diào)用obj.sayHello("John")時(shí),函數(shù)內(nèi)部的this指向的是obj對象称鳞,而obj對象內(nèi)部定義了greeting屬性涮较,因此最后的結(jié)果時(shí)“Hello, John”。
  3. 調(diào)用sayHi("John")時(shí)冈止,雖然該函數(shù)是由obj.sayHello賦值得到狂票,但是在執(zhí)行sayHi()函數(shù)時(shí),當(dāng)前的執(zhí)行上下文對象時(shí)window對象熙暴,相當(dāng)于調(diào)用window.sayHi("John")闺属,因此最后的結(jié)果是“Welcome, John”。

再看這一段代碼

<!DOCTYPE html>
<html>
    <head>
        <script>
            var obj = {
                greeting : "Hello",
                sayHello : function() {
                    setTimeout(function() {
                       alert(this.greeting)
                    }, 2000)
                }
            }
            // undefined
            obj.sayHello()
        </script>
    </head>
</html>

在這段代碼中周霉,調(diào)用obj.sayHello()時(shí)掂器,只是執(zhí)行了setTimeout()函數(shù),2s后才開始執(zhí)行setTimeout()函數(shù)參數(shù)中定義的匿名函數(shù)俱箱,而該匿名的執(zhí)行上下文對象是window唉匾,因此this指向的是window對象。顯然在window對象中并沒有定義greeting屬性匠楚,因此輸出的結(jié)果是undefined。
為了解決this指向問題厂财,可以使用函數(shù)對象的bind()方法芋簿,將this明確地綁定到某個(gè)對象上。

使用bind()方法綁定this對象

<!DOCTYPE html>
<html>
    <head>
        <script>
            var greeting = "Welcome"

            function sayHello(user) {
                alert(this.greeting + ", " + user)
            }

            var obj = {
                greeting : "Hello",
                sayHello : sayHello
            }

            var sayHi = obj.sayHello.bind(obj)
            // Hello, John
            sayHi("John")

            var obj = {
                greeting : "Hello",
                sayHello : function() {
                    setTimeout((function() {
                       alert(this.greeting)
                    }).bind(this), 2000)
                }
                // 或者用這種形式
                /*
                sayHello : function() {
                    var that = this
                    setTimeout(function() {
                        alert(that.greeting)
                    }, 2000)
                }
                */
            }
            // Hello
            obj.sayHello()
        </script>
    </head>
</html>

使用bind()方法實(shí)際上是創(chuàng)建了一個(gè)新的函數(shù)璃饱,稱為綁定函數(shù)与斤,該函數(shù)的this被綁定到參數(shù)傳入的對象。為了避免創(chuàng)建一個(gè)額外的函數(shù)荚恶,可以通過使用箭頭函數(shù)來更好的解決this問題撩穿。
箭頭函數(shù)中沒有this綁定,必須通過查找作用域來決定其值谒撼。如果箭頭函數(shù)被非箭頭函數(shù)包含食寡,則this綁定的是最近一層非箭頭函數(shù)的this;否則廓潜,this的值會被設(shè)置為全局對象抵皱。

使用箭頭函數(shù)修改上述代碼

<!DOCTYPE html>
<html>
    <head>
        <script>
            var obj = {
                greeting : "Hello",
                sayHello : function() {
                    setTimeout(() => alert(this.greeting), 2000)
                }
            }
            // Hello
            obj.sayHello()
        </script>
    </head>
</html>

alert函數(shù)參數(shù)中的this與sayHello()方法中的this一致,而這個(gè)this指向的是obj對象辩蛋,因此最后調(diào)用obj.sayHello()的結(jié)果是Hello呻畸。

箭頭函數(shù)中的this值取決于該函數(shù)外部非尖頭函數(shù)的值,且不能通過call()悼院、apply()或bind()方法來改變this的值伤为。

箭頭函數(shù)在使用時(shí)需要注意以下幾點(diǎn)

  1. 沒有this、super据途、arguments和new.target綁定绞愚。在箭頭函數(shù)中 這些值由外圍最近一層非箭頭函數(shù)決定叙甸。
  2. 不要通過new關(guān)鍵字調(diào)用。因?yàn)榧^函數(shù)不能被用作構(gòu)造函數(shù)爽醋,所以使用new關(guān)鍵字調(diào)用箭頭函數(shù)會導(dǎo)致程序報(bào)錯(cuò)蚁署。
  3. 沒有原型蚂四。因?yàn)椴荒芡ㄟ^new關(guān)鍵字調(diào)用箭頭函數(shù)光戈,因此沒有構(gòu)造原型的需求,因此箭頭函數(shù)不存在prototype這個(gè)屬性遂赠。
  4. 不可以改變this的綁定。函數(shù)內(nèi)部的this值不可被改變筷弦,在函數(shù)的生命周期內(nèi)始終保持一致烂琴。
  5. 不支持arguments對象蜕乡。箭頭函數(shù)沒有arguments綁定奸绷,所以只能通過命名參數(shù)和rest參數(shù)這兩種形式訪問函數(shù)的參數(shù)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末层玲,一起剝皮案震驚了整個(gè)濱河市号醉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌辛块,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件线椰,死亡現(xiàn)場離奇詭異士嚎,居然都是意外死亡莱衩,警方通過查閱死者的電腦和手機(jī)笨蚁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門括细,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奋单,“玉大人,你說我怎么就攤上這事呆盖〈眩” “怎么了乏苦?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵汇荐,是天一觀的道長掀淘。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么稠腊? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮我衬,結(jié)果婚禮上挠羔,老公的妹妹穿的比我還像新娘破加。我一直安慰自己,他們只是感情好了罪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布泊藕。 她就那樣靜靜地躺著娃圆,像睡著了一般踊餐。 火紅的嫁衣襯著肌膚如雪臀稚。 梳的紋絲不亂的頭發(fā)上吧寺,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天稚机,我揣著相機(jī)與錄音赖条,去河邊找鬼纬乍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛纽竣,可吹牛的內(nèi)容都是我干的蜓氨。 我是一名探鬼主播穴吹,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼刀荒,長吁一口氣:“原來是場噩夢啊……” “哼缠借!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤渠鸽,失蹤者是張志新(化名)和其女友劉穎徽缚,沒想到半個(gè)月后凿试,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體那婉,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隐岛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖童谒,靈堂內(nèi)的尸體忽然破棺而出沪羔,到底是詐尸還是另有隱情,我是刑警寧澤愉豺,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站驰贷,受9級特大地震影響括袒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狈邑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望良瞧。 院中可真熱鬧褥蚯,春花似錦赞庶、人聲如沸歧强。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽白修。三九已至熬荆,卻和暖如春累盗,著一層夾襖步出監(jiān)牢的瞬間突琳,已是汗流浹背蠢琳。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泰讽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓般贼,卻偏偏與公主長得像哼蛆,于是被迫代替她去往敵國和親人芽。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355