js中什么時候不能使用箭頭函數(shù)
箭頭函數(shù)
箭頭函數(shù)是和我們工作密切相關(guān)的東西;可以說箭頭函數(shù)的誕生,給我們的工作帶來了極大的便利。但是箭頭函數(shù)有什么缺點?什么時候不能使用箭頭函數(shù)? 這你了解嗎?
我們覺得箭頭函數(shù)很高級,可以規(guī)避 this 的問題,所有的場景下都是用箭頭函數(shù)。在不能使用的場景下使用了,出現(xiàn)了問題,你還不知道是什么問題,那這不是瞎添亂嗎!是不是!
這里給大家先提出一個問題:
const obj = { name: '張三', getName() { return this.name }, getName1: () => { return this.name } } obj.__proto__.getName2 = function() { return this.name } obj.__proto__.getName3 = () => { return this.name } console.log('普通函數(shù)',obj.getName()) console.log('普通函數(shù)',obj.getName2()) console.log('箭頭函數(shù)',obj.getName1()) console.log('箭頭函數(shù)',obj.getName3())
大家覺得會輸出什么呢?
先悄悄思考一下!
3,2,1 公布答案!
如果答錯了,也別灰心,畢竟網(wǎng)絡(luò)有著35的延遲,影響著你的操作和思考,看完這篇文章,保證你就不會答錯了!
箭頭函數(shù)有什么缺點?
沒有 arguments,如果要用,可以用 rest 參數(shù)代替。 這里我們定義一個箭頭函數(shù)和一個普通函數(shù)還有一個使用 rest 參數(shù)的箭頭函數(shù):
const fn1 = () => { console.log('arguments', arguments) } fn1(100, 200) function fn2(){ console.log('arguments', arguments) } fn2(100, 200) const fn3 = (...values) => { console.log('values', values) } fn3(100, 200)
無法通過 apply、call、bind 改變this指向 這里我們在定義一個箭頭函數(shù)和一個普通函數(shù)
const fn3 = () => { console.log('this', this) } fn3() function fn4(){ console.log('this', this) } fn4()
箭頭函數(shù)的this就是他父容器的this,不是在執(zhí)行的時候確定的,而是在定義的時候確定的。
如上圖,我們可以發(fā)現(xiàn),箭頭函數(shù)的兩次執(zhí)行的 this 都是指向了 Windows,使用call并沒有發(fā)生改變,而普通函數(shù)第一次是指向了Windows,第二次則是變成了我們傳入的
什么時候不能使用箭頭函數(shù)?
1. 對象方法中,不適用箭頭函數(shù)
const obj = { name: '張三', getName() { return this.name }, getName1: () => { return this.name } }
我們在對象中定義了普通函數(shù):getName和箭頭函數(shù) getName1,接下來我們來調(diào)用一下:
console.log('普通函數(shù)',obj.getName()) console.log('箭頭函數(shù)',obj.getName1())
這里給大家默想3s輸出什么?
公布答案:
我們發(fā)現(xiàn)箭頭函數(shù)好像并沒有獲取到值誒!
為什么對象方法中,箭頭函數(shù)的this指向不是這個對象?
- this 永遠指向函數(shù)的調(diào)用者
- 在箭頭函數(shù)中,this 指向的是定義時所在的對象,而不是使用時所在的對象。換句話說,箭頭函數(shù)沒有自己的 this,而是繼承父作用域中的 this。
obj.getName()
中this
指向函數(shù)的調(diào)用者,也就是obj
實例,因此this.name = "張三"
。
getName1()
通過箭頭函數(shù)定義,而箭頭函數(shù)是沒有自己的this
,會繼承父作用域的this
。
因此obj.getName1()
執(zhí)行時,此時的作用域指向window
,而window
沒有定義age
屬性,所有報空。
從例子可以得出:對象中定義的函數(shù)使用箭頭函數(shù)是不合適的。
2. 原型方法中,不適用箭頭函數(shù)
const obj = { name: '張三', } obj.__proto__.getName = function() { return this.name } obj.__proto__.getName1 = () => { return this.name }
我們又又又在對象中定義了普通函數(shù):getName和箭頭函數(shù) getName1,接下來我們來調(diào)用一下:
console.log(obj.getName()) console.log(obj.getName1())
這里再再再給大家默想3s輸出什么?
bang bang bang 公布答案:
為什么?
出現(xiàn)問題的原因是this指向window對象,這和使用箭頭函數(shù)在對象中定義方法十分類似。
3. 構(gòu)造函數(shù)也不行!
我們又又又定義了普通的構(gòu)造函數(shù):Foo和箭頭函數(shù) Foo1,接下來我們來調(diào)用一下:
function Foo (name, sex) { this.name = name this.sex = sex } const Foo1 = (name, sex) => { this.name = name this.sex = sex } console.log('普通的構(gòu)造函數(shù):', new Foo('張三', '男')) console.log('箭頭函數(shù):', new Foo1('張三', '男'))
不僅不行,還報錯了呢!
為什么?
構(gòu)造函數(shù)是通過 new 關(guān)鍵字來生成對象實例,生成對象實例的過程也是通過構(gòu)造函數(shù)給實例綁定 this 的過程,而箭頭函數(shù)沒有自己的 this。因此不能使用箭頭作為構(gòu)造函數(shù),也就不能通過 new 操作符來調(diào)用箭頭函數(shù)。
4. 動態(tài)上下文中的回調(diào)函數(shù)
比如,我們需要給一個按鈕添加點擊事件:
const btn1 = document.getElementById('btn1') btn1.addEventListener('click', () => { this.innerHTML = 'clicked' })
如果我們在回調(diào)中不需要使用到 this,那就啥問題也沒有,但是!使用到了 this,那么問題就大大的了!
為什么呢?
箭頭函數(shù)的 this 指向的是他的父作用域(這里就指向了 window),而不是指向這個button。這時候我們需要使用普通函數(shù)才可以。
5. Vue 生命周期和 method 中也不能使用箭頭函數(shù)
為什么不行呢?
Vue 本質(zhì)上是一個對象,我們說過對象方法中,不適用箭頭函數(shù)。他的本質(zhì)上的和對象方法中,不適用箭頭函數(shù)是一樣的。
那么我有一個問題: Vue不行,作為大熱框架之一的 react 行嗎?
回答是: react 行
因為 Vue組件本質(zhì)上是一個 JS 對象;React 組件(非Hooks)他本質(zhì)上是一個 ES6 的 class
不信的話我們測試一下就知道了
class Man { constructor(name, city) { this.name = name this.city = city } getName = () => { return this.name } } const f = new Man('李四','上海') console.log(f.getName())
劃重點
- 要熟練使用箭頭函數(shù),也要對函數(shù) this(重點) 敏感
- Vue組件本質(zhì)上是一個 JS 對象;React 組件(非Hooks)他本質(zhì)上是一個 ES6 的 class,兩者不同
到此這篇關(guān)于js中什么時候不能使用箭頭函數(shù)的文章就介紹到這了,更多相關(guān)js 箭頭函數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Unit PNG Fix.js有時候在ie6下不正常的解決辦法
本篇文章是對Unit PNG Fix.js有時候在ie6下不正常的解決辦法進行了詳細的分析介紹,需要的朋友參考下2013-06-06div+css實現(xiàn)鼠標放上去,背景跟圖片都會變化。
div+css實現(xiàn)鼠標放上去,背景跟圖片都會變化。...2007-06-06Javascript 鍵盤事件的組合使用實現(xiàn)代碼
Javascript 鍵盤事件的組合使用實現(xiàn)代碼,需要的朋友可以參考下2012-05-05webpack-url-loader 解決項目中圖片打包路徑問題
這篇文章主要介紹了webpack-url-loader 解決項目中圖片打包路徑問題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02