摘要:我們在需要動態上下文的地方不能使用箭頭函數定義需要動態上下文的函數,構造函數,需要對象作為目標的回調函數以及用箭頭函數難以理解的語句。
從開始接觸es6到在項目中使用已經有一段時間了,es6有很多優秀的新特性,其中最有價值的特性之一就是箭頭函數,他簡潔的語法以及更好理解的this值都非常的吸引我。但是新事物也是有兩面性的,箭頭函數有他的便捷有他的優點,但是他也有缺點,他的優點是代碼簡潔,this提前定義,但他的缺點也是這些,比如代碼太過簡潔,導致不好閱讀,this提前定義,導致無法使用js進行一些es5里面看起來非常正常的操作。針對這些缺點,下面我就總結一下什么情況下不該使用箭頭函數。
1.在對象上定義函數先來看下面這段代碼
var obj = { array: [1, 2, 3], sum: () => { console.log(this === window); // => true return this.array.reduce((result, item) => result + item); } }; // Throws "TypeError: Cannot read property "reduce" of undefined" obj.sum();
sum方法定義在obj對象上,當調用的時候我們發現拋出了一個TypeError,因為函數中的this是window對象,所以this.array也就是undefined。原因也很簡單,相信只要了解過es6 箭頭函數的都知道
箭頭函數沒有它自己的this值,箭頭函數內的this值繼承自外圍作用域
解決方法也很簡單,就是不用唄。這里可以用es6里函數表達式的簡潔語法,在這種情況下,this值就取決于函數的調用方式了。
var obj = { array: [1, 2, 3], sum() { console.log(this === obj); // => true return this.array.reduce((result, item) => result + item); } }; obj.sum(); // => 6
2.在原型上定義函數通過object.method()語法調用的方法使用非箭頭函數定義,這些函數需要從調用者的作用域中獲取一個有意義的this值。
在對象原型上定義函數也是遵循著一樣的規則
function Person (pName) { this.pName = pName; } Person.prototype.sayName = () => { console.log(this === window); // => true return this.pName; } var person = new Person("wdg"); person.sayName(); // => undefined
使用function函數表達式
function Person (pName) { this.pName = pName; } Person.prototype.sayName = function () { console.log(this === person); // => true return this.pName; } var person = new Person("wdg"); person.sayName(); // => wdg
所以給對象原型掛載方法時,使用function函數表達式
3.動態上下文中的回調函數this是js中非常強大的特點,他讓函數可以根據其調用方式動態的改變上下文,然后箭頭函數直接在聲明時就綁定了this對象,所以不再是動態的。
在客戶端,在dom元素上綁定事件監聽函數是非常普遍的行為,在dom事件被觸發時,回調函數中的this指向該dom,可當我們使用箭頭函數時:
var button = document.getElementById("myButton"); button.addEventListener("click", () => { console.log(this === window); // => true this.innerHTML = "Clicked button"; });
因為這個回調的箭頭函數是在全局上下文中被定義的,所以他的this是window。所以當this是由目標對象決定時,我們應該使用函數表達式:
var button = document.getElementById("myButton"); button.addEventListener("click", function() { console.log(this === button); // => true this.innerHTML = "Clicked button"; });4.構造函數中
在構造函數中,this指向新創建的對象實例
this instanceOf MyFunction === true
需要注意的是,構造函數不能使用箭頭函數,如果這樣做會拋出異常
var Person = (name) => { this.name = name; } // Uncaught TypeError: Person is not a constructor var person = new Person("wdg");
理論上來說也是不能這么做的,因為箭頭函數在創建時this對象就綁定了,更不會指向對象實例。
5.太簡短的(難以理解)函數箭頭函數可以讓語句寫的非常的簡潔,但是一個真實的項目,一般由多個開發者共同協作完成,就算由單人完成,后期也并不一定是同一個人維護,箭頭函數有時候并不會讓人很好的理解,比如
let multiply = (a, b) => b === undefined ? b => a * b : a * b; let double = multiply(2); double(3); // => 6 multiply(2, 3); // =>6
這個函數的作用就是當只有一個參數a時,返回接受一個參數b返回a*b的函數,接收兩個參數時直接返回乘積,這個函數可以很好的工作并且看起很簡潔,但是從第一眼看去并不是很好理解。
為了讓這個函數更好的讓人理解,我們可以為這個箭頭函數加一對花括號,并加上return語句,或者直接使用函數表達式:
function multiply(a, b) { if (b === undefined) { return function (b) { return a * b; } } return a * b; } let double = multiply(2); double(3); // => 6 multiply(2, 3); // => 6總結
毫無疑問,箭頭函數帶來了很多便利。恰當的使用箭頭函數可以讓我們避免使用早期的.bind()函數或者需要固定上下文的地方并且讓代碼更加簡潔。
箭頭函數也有一些不便利的地方。我們在需要動態上下文的地方不能使用箭頭函數:定義需要動態上下文的函數,構造函數,需要this對象作為目標的回調函數以及用箭頭函數難以理解的語句。在其他情況下,請盡情的使用箭頭函數。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/80600.html
摘要:同理,你只要知道改變狀態能夠實現要的功能,大體上的原理就是狀態機就可以了。總結,本文重點狀態機模式的使用場景,復雜多狀態的管理,這里注意你沒必要寫個選項卡之類的用狀態機,那反而是給自己找麻煩。 大家在寫App和一些單頁面程序的時候,經常會遇到這樣的情況:showImg(https://segmentfault.com/img/bVbsNaA?w=240&h=427);當點擊左邊的箭頭的...
showImg(https://segmentfault.com/img/remote/1460000018734296?w=900&h=500); 簡介 可讀性、性能、Spread、Reduce 在 優雅三連擊 中有同學提到了 可讀性 這個關鍵詞,就小二個人的觀點 在某個范圍內使用比較常用到的小技巧,可以提升一定的可讀性,文中提到的短路運算在初始化變量是提升可讀性的,并且在很多提倡優化if 語句...
摘要:返回布爾值,表示參數字符串是否在源字符串的頭部。參考語法返回一個布爾值與的全等操作符比較兼容環境把對象的值復制到另一個對象里淺拷貝定義方法用于將所有可枚舉的屬性的值從一個或多個源對象復制到目標對象。語法要設置其原型的對象。 一步一步似爪牙。 前言 學習es6之前我們可能并不知道es6相比es5差距在哪, 但是這并不妨礙我們站在巨人的肩膀上; 程序員就是要樂于嘗鮮; 學習es6最終目的是...
閱讀 959·2019-08-30 14:24
閱讀 998·2019-08-30 14:13
閱讀 1805·2019-08-29 17:21
閱讀 2690·2019-08-29 13:44
閱讀 1665·2019-08-29 11:04
閱讀 449·2019-08-26 10:44
閱讀 2571·2019-08-23 14:04
閱讀 914·2019-08-23 12:08