淺談ES6中箭頭函數(shù)與普通函數(shù)的區(qū)別
一、箭頭函數(shù)的基本語法示例
ES6中允許使用箭頭 => 來定義箭頭函數(shù),具體語法,我們來看一個(gè)簡(jiǎn)單的例子:
// 箭頭函數(shù)
let fun1 = (name) => {
? ? return `Hello ${name} !`;?
};
fun1('我是箭頭函數(shù)'); //Hello 我是箭頭函數(shù) !"
// 箭頭函數(shù)只有一個(gè)參數(shù),可以省去參數(shù)括號(hào)()
let fun2 = name => {
? ? return `Hello ${name} !`;?
};
fun2('我是箭頭函數(shù)'); //Hello 我是箭頭函數(shù) !"
// 箭頭函數(shù)如果函數(shù)體只有一句代碼,可以省去函數(shù)體的大括號(hào){ }
let fun3 = name => `Hello ${name} !`;
fun3('我是箭頭函數(shù)'); //Hello 我是箭頭函數(shù) !"
// 普通函數(shù)
let fun4 = function (name) {
? ? return `Hello ${name} !`; ? // 函數(shù)體
};
fun4('我是普通函數(shù)'); //Hello 我是普通函數(shù) !"從上面的基本語法示例中可以看出,箭頭函數(shù)的定義要比普通函數(shù)定義簡(jiǎn)潔、清晰得多,很快捷。
二、箭頭函數(shù)和普通函數(shù)得區(qū)別
1、箭頭函數(shù)的this指向問題(重要)
箭頭函數(shù)沒有自己的
this,它會(huì)獲取自己在定義時(shí)(注,是定義時(shí),不是調(diào)用時(shí))所處的外層執(zhí)行環(huán)境的this,并繼承這個(gè)this值。所以,箭頭函數(shù)中this的指向在它被定義的時(shí)候就已經(jīng)確定了,之后永遠(yuǎn)不會(huì)改變。
var name = 'Global';
function fun1() {
? ? //返回一個(gè)普通函數(shù)
? ? ?return function () {
? ? ? ? ? console.log(this.name);
? ? ?}
}
function fun2() {
? ? //返回一個(gè)箭頭函數(shù)
? ? ?return () => {
? ? ? ? ? console.log(this.name);
? ? ?}
}
fun1().call({name: 'Obj'}); ? ? // 'Obj'
fun2().call({name: 'Obj'}); ? ? // 'Global'從上面實(shí)例看出
fun1 返回的是一個(gè)普通函數(shù),此時(shí),通過 call 改變普通函數(shù)的 this 成功的將普通函數(shù)的 this 指向了 {name: 'Obj'} 所以輸出 Obj
fun2 返回的是一個(gè)箭頭函數(shù),由于箭頭函數(shù)的 this 是在初始化的時(shí)候就被定義了,然而它繼承了它外層 fun2 的執(zhí)行環(huán)境中的 this ,fun2 里面的this又繼承了全局的this,所以輸出 Global
再看一個(gè)實(shí)例
var name = 'Global';
var obj = {
name: 'Obj',
fun1: function(){
console.log(this.name);
},
fun2: () => {
console.log(this.name);
}
};
obj.fun1(); // 'Obj'
obj.fun2(); // 'Global'從這個(gè)實(shí)例可以看出
對(duì)象obj 里面的fun1 是一個(gè)普通函數(shù),普通函數(shù)作為對(duì)象的方法調(diào)用時(shí), this 指向它所屬的對(duì)象。此時(shí) this 指向的是當(dāng)前對(duì)象,所以返回 Obj
對(duì)象obj 里面的fun2 是一個(gè)箭頭函數(shù),箭頭函數(shù)的this 是在定義初始化的時(shí)候繼承它所處的執(zhí)行環(huán)境當(dāng)中的this,當(dāng)前fun2所處的執(zhí)行環(huán)境是 Window ,所以返回 Global
2、call() apply() bind()無法改變箭頭函數(shù)中this的指向
由于
this已經(jīng)在箭頭函數(shù)定義時(shí)候就被綁定,通過call() apply() bind()調(diào)用時(shí),只是傳入了參數(shù)而已,對(duì)this并沒有什么影響
var name = 'Global';
// 箭頭函數(shù)定義在全局作用域
let fun = () => {
console.log(this.name)
};
fun(); // 'Global'
// this的指向不會(huì)改變,永遠(yuǎn)指向Window對(duì)象
fun.call({name: 'Obj'}); // 'Global'
fun.apply({name: 'Obj'}); // 'Global'
fun.bind({name: 'Obj'})(); // 'Global'因此箭頭函數(shù)不能被修改this 指向
3、間接修改箭頭函數(shù)的this指向
如果我們?cè)谀硞€(gè)場(chǎng)景里面非要修改箭頭函數(shù)的 this指向呢
var name = 'Global';
function fun() {
//返回一個(gè)箭頭函數(shù)
return () => {
console.log(this.name);
}
}
fun()() // 'Global'
fun.call({ name: 'Obj' })() // Obj上面實(shí)例中看出fun 是一個(gè)普通函數(shù),返回一個(gè)箭頭函數(shù),我們通過call修改fun 這個(gè)普通函數(shù)的 this, 此時(shí)箭頭函數(shù)剛好繼承的是這個(gè)普通函數(shù)的 this, 所以返回 Obj, 從而達(dá)到間接修改箭頭函數(shù)的this指向問題
3、箭頭函數(shù)不能被new運(yùn)算符
通過new去實(shí)例化一個(gè)箭頭函數(shù)的時(shí)候,會(huì)報(bào)錯(cuò)
var Foo = () => {};
var foo = new Foo(); //Foo is not a constructor原因:構(gòu)造函數(shù)的new都做了些什么?簡(jiǎn)單來說,分為四步
js內(nèi)部首先會(huì)先生成一個(gè)對(duì)象;- 再把函數(shù)中的
this指向該對(duì)象; - 然后執(zhí)行構(gòu)造函數(shù)中的語句;
- 最終返回該對(duì)象實(shí)例。
由于箭頭函數(shù)沒有自己的this,它的this是繼承外部執(zhí)行環(huán)境中的this,這個(gè)時(shí)候通過new運(yùn)算符進(jìn)行實(shí)例化時(shí)候,且this指向永遠(yuǎn)不會(huì)隨在哪里調(diào)用、被誰調(diào)用而改變,所以箭頭函數(shù)不能作為構(gòu)造函數(shù)使用
4、箭頭函數(shù)沒有原型prototype
let Foo = () => {
console.log('Hello World !')
};
console.log(Foo.prototype); // undefined5、箭頭函數(shù)沒有arguments,然而可用 REST參數(shù),擴(kuò)展運(yùn)算符(三個(gè)點(diǎn))...解決
// 普通函數(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ù)得替代方法是用擴(kuò)展運(yùn)算符(三個(gè)點(diǎn))...解決
let fun = (...args) => {
console.log(args)
};
fun(1,2); // [1, 2]6、箭頭函數(shù)不能換行
let fun = ()
=> 1; // SyntaxError: expected expression, got '=>'7、箭頭函數(shù)一條語句返回對(duì)象字面量,需要加括號(hào)
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ù)的解析順序相對(duì)||靠前
let fun = false || function() {}; // ok
let fun1 = false || () => {}; ? // Malformed arrow function parameter list
let fun2 = false || (() => {}); ? ?// ok9、箭頭函數(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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
出現(xiàn)“不能執(zhí)行已釋放的Script代碼”錯(cuò)誤的原因及解決辦法
出現(xiàn)“不能執(zhí)行已釋放的Script代碼”錯(cuò)誤的原因及解決辦法...2007-08-08
移動(dòng)web開發(fā)之touch事件實(shí)例詳解
下面小編就為大家分享一篇移動(dòng)web開發(fā)之touch事件實(shí)例詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-01-01
JS擴(kuò)展String.prototype.format字符串拼接的功能
這篇文章主要介紹了JS擴(kuò)展String.prototype.format字符串拼接的功能,需要的朋友可以參考下2018-03-03
如何基于小程序?qū)崿F(xiàn)發(fā)送語音消息及轉(zhuǎn)文字功能
最近為小程序增加語音識(shí)別轉(zhuǎn)文字的功能,坑路不斷,特此記錄,下面這篇文章主要給大家介紹了關(guān)于如何基于小程序?qū)崿F(xiàn)發(fā)送語音消息及轉(zhuǎn)文字功能的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
使用JavaScript字符串解決回文數(shù)的方案詳解
這篇文章主要介紹了使用JavaScript字符串解決回文數(shù)的方案,JavaScript中的字符串是一種數(shù)據(jù)類型,用于表示文本數(shù)據(jù),字符串可以包含任意字符序列,包括字母、數(shù)字、符號(hào)和空格,靈活掌握字符串的解決問題思想,巧用字符串解決回文數(shù),需要的朋友可以參考下2024-05-05
5個(gè)經(jīng)過實(shí)戰(zhàn)驗(yàn)證的JavaScript性能優(yōu)化技巧分享
在現(xiàn)代Web開發(fā)中,JavaScript性能優(yōu)化是每個(gè)開發(fā)者都必須面對(duì)的挑戰(zhàn),本文將揭示5個(gè)經(jīng)過實(shí)戰(zhàn)驗(yàn)證的JavaScript性能優(yōu)化技巧,其中第三個(gè)技巧更是被90%的開發(fā)者所忽視,需要的朋友可以參考下2026-03-03

