您好,登錄后才能下訂單哦!
這篇文章主要介紹了ES6中箭頭函數是什么及怎么使用的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇ES6中箭頭函數是什么及怎么使用文章都會有所收獲,下面我們一起來看看吧。
ES6中允許使用=>來定義函數。箭頭函數相當于匿名函數,并簡化了函數定義。
// 箭頭函數let fn = (name) => { // 函數體 return `Hello ${name} !`;};// 等同于let fn = function (name) { // 函數體 return `Hello ${name} !`;};
箭頭函數在語法上比普通函數簡潔多。箭頭函數就是采用箭頭=>來定義函數,省去關鍵字function。
函數的參數放在=>前面的括號中,函數體跟在=>后的花括號中
如果箭頭函數沒有參數,寫空括號
//沒有參數,寫空括號 let fn = () => { console.log('hello'); };
如果箭頭函數有一個參數,也可以省去包裹參數的括號
//只有一個參數,可以省去參數括號 let fn = name => { console.log(`hello ${name}!`) };
如果箭頭函數有多個參數,將參數依次用逗號(,)分隔,包裹在括號中。
let fn = (val1, val2, val3, val4) => { return [val1, val2, val3, val4]; }
如果箭頭函數的函數體只有一句執行代碼,簡單返回某個變量或者返回一個簡單的js表達式,可以省去函數體花括號{ }
//返回某個簡單變量vallet f = val => val;// 等同于let f = function (val) { return val };//返回一個簡單的js表達式num1+num2let sum = (num1, num2) => num1 + num2;// 等同于let sum = function(num1, num2) { return num1 + num2;};
如果箭頭函數的函數體只有一句代碼,返回的不是變量和簡單的js表達式,而是一個對象。
//錯誤寫法—花括號會被解釋為函數體 let getItem = id => { id: id, name: 'gaby' };//正確寫法 let getItem = id => ({ id: id, name: 'gaby' });
如果箭頭函數的函數體只有一條語句且不需要返回值(最常用于回調函數),加上void關鍵字
let fn = () => void doesNotReturn();
箭頭函數用于回調函數,常見簡潔
//栗子1//普通函數 [1, 2, 3].map(function (x) { return x + x; });//ES6箭頭函數[1, 2, 3].map(x => x + x);
//栗子2//普通函數 var result = [2, 4, 5, 1, 6].sort(function (a, b) { return a - b; });//ES6箭頭函數 var result = [2, 4, 5, 1, 6].sort((a, b) => a - b);
let fn = () => { console.log('Hello World !') }; console.log(fn.prototype); // undefined
箭頭函數沒有自己的this指向,它會捕獲自己定義所處的外層執行環境,并且繼承這個this值。箭頭函數的this指向在被定義的時候就確定了,之后永遠都不會改變。(!永遠)
var id = 'Global'; //普通函數 function fn1() { setTimeout(function () { console.log(this.id) }, 1000); } //箭頭函數 function fn2() { setTimeout(() => { console.log(this.id) }, 1000); } fn1.call({ id: 'obj' });//Global fn2.call({ id: 'obj' });//obj
解析:普通函數的setTimeout 一秒后執行是在全局作用域,所有this指向window對象,this.id指向了全局變量id,輸出Golbal。箭頭函數的this在定義的時候就確定了,繼承fn2的執行環境中的this,fn2的this指向被call方法改變綁定到obj這個對象
var id = 'Global'; var obj = { id: 'OBJ', a: function () { console.log(this.id) },//方法a普通函數定義 b: () => { console.log(this.id) }//方法b用箭頭函數定義 }; obj.a();//OBJ obj.b();//Global
解析:普通函數作為對象的方法調用,this指向所屬的對象(誰調用它就指向誰),this.id 就是obj.id;箭頭函數繼承定義它的執行環境的this,指向window對象,指向全局變量,輸出Global。花括號{}無法形成一個單獨的執行環境,所有它依然在全局中。
.call()/.apply()/.bind()方法可以用來動態修改函數執行時this的指向,但由于箭頭函數的this定義時就已經確定且永遠不會改變
var name = 'gaby' var person = { name: 'gabrielle', say: function () { console.log('say hello', this.name) }, //普通函數 say2: () => { console.log('say2 hello', this.name) } //箭頭函數 } person.say.call({ name: 'Mike' }) person.say2.call({ name: 'Amy' })
解析:say的普通函數通過call調用已經改變this指向。say2箭頭函數調用call綁定嘗試改變this指向,但是仍然打印出外一層普通函數的this指向,window對象的全局變量name。
間接修改:修改被繼承的普通函數的this指向,箭頭函數的this指向也會跟著改變。
箭頭函數的this指向定義時所在的外層第一個普通函數,跟使用的位置沒有關系。
let al let aObj = { msg: 'a的this指向' }; bObj = { msg: 'b的this指向' }; a.call(aObj); //將a的this指向aObj b.call(bObj); //將b普通函數的this指向bObj 箭頭函數內部的this指向也會指向bObj function b() { al(); } function a() { al = () => { console.log(this, 'this指向定義時外層第一個普通函數 ') }; }
箭頭函數的this指向繼承自外層第一個普通函數的this,那么如果沒有外層函數,它的this指向哪里?
this的綁定規則:非嚴格模式下,默認綁定的this指向全局對象,嚴格模式下this指向undefined。
如果箭頭函數外層沒有普通函數繼承,箭頭函數在全局作用域下,嚴格模式和非嚴格模式下它的this都會指向window(全局對象)
箭頭函數中的this引用的是最近作用域中的this,是向外層作用域中,一層層查找this,直到有this的定義。
構造函數做了什么?
JS內部首先會先生成一個對象
再把函數中的this指向該對象
然后執行構造函數中的語句
最終返回該對象實例
箭頭函數沒有自己的this,this繼承外層執行環境中的this,且this永遠不會改變。new會報錯
let fn = (name, age) => { this.name = name; this.age = age; }; let person = new fn('gaby', 20)
ES6新引入的屬性,普通函數可以通過new調用,new.target返回該函數的引用。用于確定構造函數是否為new調用。箭頭函數并不能作為構造函數使用new,自然也不支持new.targer。
let fn = () => { console.log(new.target) }; fn()
new fn2(); function fn2() { let fn = () => { console.log(new.target) }; fn(); }
箭頭函數的this指向全局對象,會報arguments未聲明的錯。
let fn = name => { console.log(arguments) } let fn2 = function (name) { console.log(arguments) } //fn() fn2()
let fn = name => { console.log(arguments) } let fn2 = function (name) { console.log(arguments) } fn() fn2()
解析:普通函數可以打印arguments,箭頭函數報錯。因為箭頭函數處于全局作用域中,在全局作用域沒有arguments的定義,箭頭函數本身沒有arguments,所以報錯。
let fn2 = function (name) { console.log('fn2:', arguments) let fn = name => { console.log('fn:', arguments) } fn() } fn2('gaby')
解析:兩個函數打印的argument相同,都是fn2函數的arguments。
總結
箭頭函數沒有自己的arguments對象。在箭頭函數中訪問arguments實際上獲得的是外層局部(函數)執行環境中的值。
rest是ES6的API,用于獲取函數不定數量的參數數組。這個API可以用來替代arguments。
//形式是...變量名 let fn = (first, ...arr) => { console.log(first, arr); } fn(1, 2, 3, 4);
解析:rest 參數搭配的變量是一個數組,該變量將多余的參數放入數組中。獲取函數的第一個確定的參數,以及用一個變量接收其他剩余函數的實例。
rest必須是函數的最后一位參數
let a = (first, ...rest, three) => { console.log(first, rest, three); }; a(1, 2, 3, 4);
函數的length屬性不包括rest
箭頭函數和普通函數都可以使用rest參數,而arguments只能普通函數用。
接收參數rest比arguments更加靈活,完全可以自定義。
rest是一個真正的數組可以使用數組API,arguments只是一個類數組。
function fn(name, name) { console.log('fn2:', name) } let fn2 = (name, name) => { console.log('fn:', name) } fn('wang', 'gaby') fn2('wang', 'gaby')
函數箭頭一條語句返回對象字面量,需要加括號。
箭頭函數在參數和箭頭之間不能換行
箭頭函數的解析順序相對||靠前
對象無法構造單獨的作用域
var name = 'gaby' var person = { name: 'gabrielle', say: function () { console.log('say hello', this.name) }, //普通函數 say2: () => { console.log('say2 hello', this.name) } //箭頭函數 } person.say() person.say2()
解析:person.say2()方法是一個箭頭函數,調用person.say2()的時候this指向全局對象,達不到預期。對象無法構成單獨的作用域,定義say2()箭頭函數的時候作用域在全局作用域。
var button = document.querySelector('.btn'); button.addEventListener('click', () => { this.classList.toggle('on'); });
解析:報錯。按鈕點擊是一個回調函數,而箭頭函數內部的this指向外一層普通函數的this,在這里就是window,所以報錯。改成普通函數就不會報錯
(1)箭頭函數語法更簡潔清晰,快捷。
(2)箭頭函數沒有原型prototype,并不會自己創建this,并且this不能被修改,call等都不能修改到。只能間接修改被繼承的this
(3)箭頭函數的this在定義時就定了,繼承外一層的普通函數
(4)如果箭頭函數外一層再外一層都不能找到普通函數,在嚴格和非嚴格情況下都會指向window對象
(5)箭頭函數的this指向全局,使用arguments會報未聲明的錯誤
(6)箭頭函數的this指向外一層的普通函數,使用argument繼承該普通函數
(7)箭頭函數不能構造函數,不能new.target,不能new,沒有constructor
(8)箭頭函數不支持重復命名參數,普通函數可以重復命名參數
關于“ES6中箭頭函數是什么及怎么使用”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“ES6中箭頭函數是什么及怎么使用”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。