這篇文章主要介紹es6中箭頭函數和普通函數的區別有哪些,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
創新互聯是一家集網站建設,洛寧企業網站建設,洛寧品牌網站建設,網站定制,洛寧網站建設報價,網絡營銷,網絡優化,洛寧網站推廣為一體的創新建站企業,幫助傳統企業提升企業形象加強企業競爭力。可充分滿足這一群體相比中小企業更為豐富、高端、多元的互聯網需求。同時我們時刻保持專業、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學習、思考、沉淀、凈化自己,讓我們為更多的企業打造出實用型網站。
區別:1、箭頭函數的定義要比普通函數定義簡潔、清晰得多,很快捷;2、箭頭函數不會創建自己的this,而普通函數會;3、箭頭函數不能作為構造函數使用,而箭頭函數能作為構造函數使用;4、箭頭函數沒有自己的arguments,而箭頭函數有。
本教程操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。
箭頭函數是前端面試環節的一個高頻考點,箭頭函數是ES6的API,相信很多人都知道,因為它的語法比一般的函數更簡潔,所以深受大家的喜愛。
一、基本語法
ES6中允許使用箭頭=>
來定義箭頭函數,具體語法,我們來看一個簡單的例子:
// 箭頭函數 let fun = (name) => { // 函數體 return `Hello ${name} !`; }; // 等同于 let fun = function (name) { // 函數體 return `Hello ${name} !`; };
可以看出,定義箭頭函在數語法上要比普通函數簡潔得多。箭頭函數省去了function
關鍵字,采用箭頭=>
來定義函數。函數的參數放在=>
前面的括號中,函數體跟在=>
后的花括號中。
關于箭頭函數的參數:
①如果箭頭函數沒有參數,直接寫一個空括號即可。
②如果箭頭函數的參數只有一個,也可以省去包裹參數的括號。
③如果箭頭函數有多個參數,將參數依次用逗號(,)分隔,包裹在括號中即可。
// 沒有參數 let fun1 = () => { console.log(111); }; // 只有一個參數,可以省去參數括號 let fun2 = name => { console.log(`Hello ${name} !`) }; // 有多個參數 let fun3 = (val1, val2, val3) => { return [val1, val2, val3]; };
關于箭頭函數的函數體:
①如果箭頭函數的函數體只有一句代碼,就是簡單返回某個變量或者返回一個簡單的JS表達式,可以省去函數體的大括號{ }。
let f = val => val; // 等同于 let f = function (val) { return val }; let sum = (num1, num2) => num1 + num2; // 等同于 let sum = function(num1, num2) { return num1 + num2; };
②如果箭頭函數的函數體只有一句代碼,就是返回一個對象,可以像下面這樣寫:
// 用小括號包裹要返回的對象,不報錯 let getTempItem = id => ({ id: id, name: "Temp" }); // 但絕不能這樣寫,會報錯。 // 因為對象的大括號會被解釋為函數體的大括號 let getTempItem = id => { id: id, name: "Temp" };
③如果箭頭函數的函數體只有一條語句并且不需要返回值(最常見是調用一個函數),可以給這條語句前面加一個void
關鍵字
let fn = () => void doesNotReturn();
箭頭函數最常見的用處就是簡化回調函數。
// 例子一 // 正常函數寫法 [1,2,3].map(function (x) { return x * x; }); // 箭頭函數寫法 [1,2,3].map(x => x * x); // 例子二 // 正常函數寫法 var result = [2, 5, 1, 4, 3].sort(function (a, b) { return a - b; }); // 箭頭函數寫法 var result = [2, 5, 1, 4, 3].sort((a, b) => a - b);
二、箭頭函數與普通函數的區別
1、語法更加簡潔、清晰
從上面的基本語法示例中可以看出,箭頭函數的定義要比普通函數定義簡潔、清晰得多,很快捷。
2、箭頭函數不會創建自己的this(重要!!深入理解!!)
我們先來看看MDN上對箭頭函數this
的解釋。
箭頭函數不會創建自己的
this
,所以它沒有自己的this
,它只會從自己的作用域鏈的上一層繼承this
。
箭頭函數沒有自己的this
,它會捕獲自己在定義時(注意,是定義時,不是調用時)所處的外層執行環境的this
,并繼承這個this
值。所以,箭頭函數中this
的指向在它被定義的時候就已經確定了,之后永遠不會改變。
來看個例子:
var id = 'Global'; function fun1() { // setTimeout中使用普通函數 setTimeout(function(){ console.log(this.id); }, 2000); } function fun2() { // setTimeout中使用箭頭函數 setTimeout(() => { console.log(this.id); }, 2000) } fun1.call({id: 'Obj'}); // 'Global' fun2.call({id: 'Obj'}); // 'Obj'
上面這個例子,函數fun1
中的setTimeout
中使用普通函數,2秒后函數執行時,這時函數其實是在全局作用域執行的,所以this
指向Window
對象,this.id
就指向全局變量id
,所以輸出'Global'
。
但是函數fun2
中的setTimeout
中使用的是箭頭函數,這個箭頭函數的this
在定義時就確定了,它繼承了它外層fun2
的執行環境中的this
,而fun2
調用時this
被call
方法改變到了對象{id: 'Obj'}
中,所以輸出'Obj'
。
再來看另一個例子:
var id = 'GLOBAL'; var obj = { id: 'OBJ', a: function(){ console.log(this.id); }, b: () => { console.log(this.id); } }; obj.a(); // 'OBJ' obj.b(); // 'GLOBAL'
上面這個例子,對象obj
的方法a
使用普通函數定義的,普通函數作為對象的方法調用時,this
指向它所屬的對象。所以,this.id
就是obj.id
,所以輸出'OBJ'
。
但是方法b
是使用箭頭函數定義的,箭頭函數中的this
實際是繼承的它定義時所處的全局執行環境中的this
,所以指向Window
對象,所以輸出'GLOBAL'
。(這里要注意,定義對象的大括號{}
是無法形成一個單獨的執行環境的,它依舊是處于全局執行環境中!!)
3、箭頭函數繼承而來的this指向永遠不變(重要!!深入理解!!)
上面的例子,就完全可以說明箭頭函數繼承而來的this
指向永遠不變。對象obj
的方法b
是使用箭頭函數定義的,這個函數中的this
就永遠指向它定義時所處的全局執行環境中的this
,即便這個函數是作為對象obj
的方法調用,this
依舊指向Window
對象。
4、.call()/.apply()/.bind()無法改變箭頭函數中this的指向
.call()
/.apply()
/.bind()
方法可以用來動態修改函數執行時this
的指向,但由于箭頭函數的this
定義時就已經確定且永遠不會改變。所以使用這些方法永遠也改變不了箭頭函數this
的指向,雖然這么做代碼不會報錯。
var id = 'Global'; // 箭頭函數定義在全局作用域 let fun1 = () => { console.log(this.id) }; fun1(); // 'Global' // this的指向不會改變,永遠指向Window對象 fun1.call({id: 'Obj'}); // 'Global' fun1.apply({id: 'Obj'}); // 'Global' fun1.bind({id: 'Obj'})(); // 'Global'
5、箭頭函數不能作為構造函數使用
我們先了解一下構造函數的new都做了些什么?簡單來說,分為四步: ① JS內部首先會先生成一個對象; ② 再把函數中的this指向該對象; ③ 然后執行構造函數中的語句; ④ 最終返回該對象實例。
但是!!因為箭頭函數沒有自己的this
,它的this
其實是繼承了外層執行環境中的this
,且this
指向永遠不會隨在哪里調用、被誰調用而改變,所以箭頭函數不能作為構造函數使用,或者說構造函數不能定義成箭頭函數,否則用new
調用時會報錯!
let Fun = (name, age) => { this.name = name; this.age = age; }; // 報錯 let p = new Fun('cao', 24);
6、箭頭函數沒有自己的arguments
箭頭函數沒有自己的arguments
對象。在箭頭函數中訪問arguments
實際上獲得的是外層局部(函數)執行環境中的值。
// 例子一 let fun = (val) => { console.log(val); // 111 // 下面一行會報錯 // Uncaught ReferenceError: arguments is not defined // 因為外層全局環境沒有arguments對象 console.log(arguments); }; fun(111); // 例子二 function outer(val1, val2) { let argOut = arguments; console.log(argOut); // ① let fun = () => { let argIn = arguments; console.log(argIn); // ② console.log(argOut === argIn); // ③ }; fun(); } outer(111, 222);
上面例子二,①②③處的輸出結果如下:
很明顯,普通函數outer
內部的箭頭函數fun
中的arguments
對象,其實是沿作用域鏈向上訪問的外層outer
函數的arguments
對象。
可以在箭頭函數中使用rest參數代替arguments對象,來訪問箭頭函數的參數列表!!
7、箭頭函數沒有原型prototype
let sayHi = () => { console.log('Hello World !') }; console.log(sayHi.prototype); // undefined
8、箭頭函數不能用作Generator函數,不能使用yeild關鍵字
以上是“es6中箭頭函數和普通函數的區別有哪些”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注創新互聯行業資訊頻道!
分享題目:es6中箭頭函數和普通函數的區別有哪些
分享路徑:http://m.newbst.com/article36/gpjssg.html
成都網站建設公司_創新互聯,為您提供網站排名、關鍵詞優化、服務器托管、品牌網站設計、ChatGPT、建站公司
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯