淺談ES6中箭頭函數(shù)與普通函數(shù)的區(qū)別
一、箭頭函數(shù)的基本語法示例
ES6中允許使用箭頭 => 來定義箭頭函數(shù),具體語法,我們來看一個簡單的例子:
// 箭頭函數(shù) let fun1 = (name) => { ? ? return `Hello ${name} !`;? }; fun1('我是箭頭函數(shù)'); //Hello 我是箭頭函數(shù) !" // 箭頭函數(shù)只有一個參數(shù),可以省去參數(shù)括號() let fun2 = name => { ? ? return `Hello ${name} !`;? }; fun2('我是箭頭函數(shù)'); //Hello 我是箭頭函數(shù) !" // 箭頭函數(shù)如果函數(shù)體只有一句代碼,可以省去函數(shù)體的大括號{ } let fun3 = name => `Hello ${name} !`; fun3('我是箭頭函數(shù)'); //Hello 我是箭頭函數(shù) !" // 普通函數(shù) let fun4 = function (name) { ? ? return `Hello ${name} !`; ? // 函數(shù)體 }; fun4('我是普通函數(shù)'); //Hello 我是普通函數(shù) !"
從上面的基本語法示例中可以看出,箭頭函數(shù)的定義要比普通函數(shù)定義簡潔、清晰得多,很快捷。
二、箭頭函數(shù)和普通函數(shù)得區(qū)別
1、箭頭函數(shù)的this指向問題(重要)
箭頭函數(shù)沒有自己的
this
,它會獲取自己在定義時(注,是定義時,不是調(diào)用時)所處的外層執(zhí)行環(huán)境的this
,并繼承這個this
值。所以,箭頭函數(shù)中this
的指向在它被定義的時候就已經(jīng)確定了,之后永遠不會改變。
var name = 'Global'; function fun1() { ? ? //返回一個普通函數(shù) ? ? ?return function () { ? ? ? ? ? console.log(this.name); ? ? ?} } function fun2() { ? ? //返回一個箭頭函數(shù) ? ? ?return () => { ? ? ? ? ? console.log(this.name); ? ? ?} } fun1().call({name: 'Obj'}); ? ? // 'Obj' fun2().call({name: 'Obj'}); ? ? // 'Global'
從上面實例看出
fun1
返回的是一個普通函數(shù),此時,通過 call
改變普通函數(shù)的 this
成功的將普通函數(shù)的 this
指向了 {name: 'Obj'}
所以輸出 Obj
fun2
返回的是一個箭頭函數(shù),由于箭頭函數(shù)的 this
是在初始化的時候就被定義了,然而它繼承了它外層 fun2
的執(zhí)行環(huán)境中的 this
,fun2
里面的this
又繼承了全局的this
,所以輸出 Global
再看一個實例
var name = 'Global'; var obj = { name: 'Obj', fun1: function(){ console.log(this.name); }, fun2: () => { console.log(this.name); } }; obj.fun1(); // 'Obj' obj.fun2(); // 'Global'
從這個實例可以看出
對象obj
里面的fun1
是一個普通函數(shù),普通函數(shù)作為對象的方法調(diào)用時, this
指向它所屬的對象。此時 this
指向的是當前對象,所以返回 Obj
對象obj
里面的fun2
是一個箭頭函數(shù),箭頭函數(shù)的this
是在定義初始化的時候繼承它所處的執(zhí)行環(huán)境當中的this
,當前fun2所處的執(zhí)行環(huán)境是 Window
,所以返回 Global
2、call() apply() bind()無法改變箭頭函數(shù)中this的指向
由于
this
已經(jīng)在箭頭函數(shù)定義時候就被綁定,通過call() apply() bind()
調(diào)用時,只是傳入了參數(shù)而已,對this
并沒有什么影響
var name = 'Global'; // 箭頭函數(shù)定義在全局作用域 let fun = () => { console.log(this.name) }; fun(); // 'Global' // this的指向不會改變,永遠指向Window對象 fun.call({name: 'Obj'}); // 'Global' fun.apply({name: 'Obj'}); // 'Global' fun.bind({name: 'Obj'})(); // 'Global'
因此箭頭函數(shù)不能被修改this
指向
3、間接修改箭頭函數(shù)的this指向
如果我們在某個場景里面非要修改箭頭函數(shù)的 this
指向呢
var name = 'Global'; function fun() { //返回一個箭頭函數(shù) return () => { console.log(this.name); } } fun()() // 'Global' fun.call({ name: 'Obj' })() // Obj
上面實例中看出fun
是一個普通函數(shù),返回一個箭頭函數(shù),我們通過call修改fun 這個普通函數(shù)的 this
, 此時箭頭函數(shù)剛好繼承的是這個普通函數(shù)的 this
, 所以返回 Obj
, 從而達到間接修改箭頭函數(shù)的this
指向問題
3、箭頭函數(shù)不能被new運算符
通過new去實例化一個箭頭函數(shù)的時候,會報錯
var Foo = () => {}; var foo = new Foo(); //Foo is not a constructor
原因:構(gòu)造函數(shù)的new都做了些什么?簡單來說,分為四步
js
內(nèi)部首先會先生成一個對象;- 再把函數(shù)中的
this
指向該對象; - 然后執(zhí)行構(gòu)造函數(shù)中的語句;
- 最終返回該對象實例。
由于箭頭函數(shù)沒有自己的this
,它的this
是繼承外部執(zhí)行環(huán)境中的this
,這個時候通過new
運算符進行實例化時候,且this
指向永遠不會隨在哪里調(diào)用、被誰調(diào)用而改變,所以箭頭函數(shù)不能作為構(gòu)造函數(shù)使用
4、箭頭函數(shù)沒有原型prototype
let Foo = () => { console.log('Hello World !') }; console.log(Foo.prototype); // undefined
5、箭頭函數(shù)沒有arguments,然而可用 REST參數(shù),擴展運算符(三個點)...解決
// 普通函數(shù) function fun1() { console.log(arguments) } //箭頭函數(shù) let fun2 = () => { console.log(arguments) }; fun1(1,2); // Arguments(2) [1, 2, callee: ?, Symbol(Symbol.iterator): ?] fun2(1,2); // arguments is not defined
可以看出箭頭函數(shù)是沒有arguments
得,不過不用擔(dān)心,箭頭函數(shù)得替代方法是用擴展運算符(三個點)...解決
let fun = (...args) => { console.log(args) }; fun(1,2); // [1, 2]
6、箭頭函數(shù)不能換行
let fun = () => 1; // SyntaxError: expected expression, got '=>'
7、箭頭函數(shù)一條語句返回對象字面量,需要加括號
let fun = () => { foo: 1 }; fun(); // undefined let fun1 = () => ({ foo: 1 }); fun1(); // {foo: 1} let fun2 = () => { foo: function() {} }; ?? // SyntaxError: function statement requires a name let fun3 = () => ({ foo: function() {} }); ?
8、箭頭函數(shù)的解析順序相對||靠前
let fun = false || function() {}; // ok let fun1 = false || () => {}; ? // Malformed arrow function parameter list let fun2 = false || (() => {}); ? ?// ok
9、箭頭函數(shù)不能用作Generator函數(shù),不能使用yeild關(guān)鍵字
yield 關(guān)鍵字通常不能在箭頭函數(shù)中使用(除非是嵌套在允許使用的函數(shù)內(nèi))。因此,箭頭函數(shù)不能用作函數(shù)生成器。。
三、參考資料
四、結(jié)束語
到此這篇關(guān)于淺談ES6中箭頭函數(shù)與普通函數(shù)的區(qū)別的文章就介紹到這了,更多相關(guān)ES6 箭頭函數(shù)與普通函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js 開發(fā)之a(chǎn)utocomplete="off"在chrom中失效的解決辦法
這篇文章主要介紹了js 開發(fā)之a(chǎn)utocomplete="off"在chrom中失效的解決辦法的相關(guān)資料,希望通過本文能幫助到大家,解決遇到這樣的問題,需要的朋友可以參考下2017-09-09JavaScript精煉之構(gòu)造函數(shù) Constructor及Constructor屬性詳解
對象的constructor屬性用于返回創(chuàng)建該對象的函數(shù),也就是我們常說的構(gòu)造函數(shù),除了創(chuàng)建對象,構(gòu)造函數(shù)(constructor) 還做了另一件有用的事情—自動為創(chuàng)建的新對象設(shè)置了原型對象(prototype object)2015-11-11JavaScript:void(0)用法及一些常見問題解決辦法
這篇文章主要介紹了javascript:void(0)在JavaScript中的用法,探討了其防止鏈接默認行為的作用,提供了使用示例,并針對常見問題如與#的區(qū)別、事件綁定和鍵盤訪問進行了講解,需要的朋友可以參考下2024-12-12javascript檢查瀏覽器是否已經(jīng)啟用XX功能
本文給大家分享的是檢測瀏覽器是否支持cookie功能,檢查瀏覽器是否已經(jīng)啟用Java支持功能以及獲取當前瀏覽器的信息,十分的實用,有需要的小伙伴可以參考下。2015-07-07