JavaScript 是一門非常靈活和強大的語言汰现,它擁有許多新穎和有趣的特性逾条,讓我們可以更方便地處理異步操作,編寫更優(yōu)雅和清晰的代碼座柱。
你一定聽說過 async/await、Promise物舒、Generator 等等色洞。
但是,你是否真正理解了這些特性背后的原理和機制呢冠胯?
例如火诸,如何判斷一個函數(shù)是否標記了 async
今天跟著子辰來看這道字節(jié)的面試題,相信會對你有所幫助
/**
* 字節(jié)面試題:
* 判斷傳入的函數(shù)是否標記了 async
* */
function isAsyncFunction(func) {}
isAsyncFunction(() => {}); // expect:false
isAsyncFunction(async () => {}); // expect:true
通過本文你將會學習如何用一種簡單而準確的方法來判斷一個函數(shù)是否標記了 async荠察,以及這個方法背后的原理和知識點置蜀。
讓我們開始吧奈搜!
分析解題
面試題要求我們寫一個函數(shù)來判斷傳入的函數(shù)是否標記了 async,并給出兩個示例盯荤,傳入一個普通函數(shù)的話就返回 false馋吗,傳入一個 async 函數(shù)的話就返回 true
子辰首先幫你排除一個錯誤的解答,有些同學可能會想到廷雅,可以在 isAsyncFunction 里直接調(diào)用 func耗美,如果它返回的是一個 Promise,那么它就標記了 async航缀,但是這樣做是不行的商架。
首先你并不知道這個函數(shù)要傳遞多少個參數(shù),參數(shù)怎么傳遞芥玉,有些函數(shù)可能有很多個參數(shù)蛇摸,但是你一個參數(shù)不傳就可能會報錯了。
其次是這個函數(shù)可能沒有標記 async 卻依然返回 Promise灿巧,比如 function f(){ return new Promise() }
赶袄。
還有一種情況就是這個函數(shù)里有副作用,比如更改了全局的一些東西或者是發(fā)送了一個請求抠藕,那么這一調(diào)用這個函數(shù)的話饿肺,就造成了副作用,所以說調(diào)用是肯定不行的盾似。
那么現(xiàn)在我們沒思路就先觀察一下普通函數(shù)和標記了 async 的函數(shù)到底有什么區(qū)別仗嗦。
我們先在控制臺中輸出一下標記了 async 的函數(shù)建蹄。
可以看到在 async 函數(shù)的原型上有一個符號篙耗,而且是一個知名的符號懒闷,叫做 toStringTag,它的值是 AsyncFunction告抄。
我們在看一下普通函數(shù)撰茎。
可以看到在普通函數(shù)的原型上就沒有這么一個知名符號。
我們暫時不去考慮這個知名符號到底有什么作用打洼,由于它們存在這樣一個差別龄糊,所以說代碼就很好寫了,我們只要判斷這個函數(shù)是否帶這個知名符號拟蜻,并且值是 AsyncFunction 就可以了绎签。
function isAsyncFunction(func) {
return func[Symbol.toStringTag] === "AsyncFunction";
}
console.log("function >>> ", isAsyncFunction(() => {}));
console.log("async function >>> ", isAsyncFunction(async () => {}));
console.log("function Promise >>> ", isAsyncFunction(() => {return new Promise()}));
可以看到無論什么情況都是可以的,現(xiàn)在可以準確的判斷這個函數(shù)酝锅,到底有沒有標記 async 了诡必。
接下來我們研究一下這個知名符號到底是什么作用。
在過去要判斷一個東西它是不是數(shù)組,經(jīng)常是這么判斷的爸舒。
通過字符串的第二個單詞就可以知道它是不是一個數(shù)組了蟋字,那么這種表達格式以前只針對部分的內(nèi)置對象有效。
如果說是我們自己寫的對象就是無效的扭勉。
得到的字符串里并不能把這個類型 F 給表達出來鹊奖,而且在過去這種行為是無法更改的。
但是到了 ES6 給我們提供了一種方式涂炎,可以更改這個行為忠聚,更改方式就是知名符號。
我們給 F 的原型上的 Symbol.toStringTag 賦值為一個字符串類型的大寫 F唱捣。
由于有了知名符號两蟀,我們可以看到 f 的原型上就出現(xiàn)了一個知名符號 "F",然后 Object.prototype.toString.call()
返回字符串的第二個單詞就變成了我們設置的 F震缭。
同理可得赂毯,async 函數(shù)它的原型上既然有這個知名符號,所以我們也可以使用下圖這種方式來判斷拣宰。
總結
通過這篇文章党涕,我們了解了如何用知名符號 Symbol.toStringTag
來判斷一個函數(shù)是否標記了 async。
這個知名符號是 ES6 新增的一種特性巡社,它可以讓我們自定義對象的類型膛堤,并且影響 Object.prototype.toString
方法的返回值。
這個知名符號不僅可以用來判斷 async 函數(shù)晌该,還可以用來判斷其他內(nèi)置對象骑祟,比如數(shù)組、Map气笙、Set 等等。
它也可以讓我們給自己定義的對象添加一個更有意義的類型怯晕,方便我們進行類型檢測和區(qū)分潜圃。
知名符號是一個非常有用的工具,我們應該掌握它的用法和原理舟茶,以便在實際開發(fā)中靈活運用谭期。