摘要:首先是通過(guò)創(chuàng)建一個(gè)函數(shù),然后向其傳遞參與計(jì)算的值,也就是說(shuō)應(yīng)該是返回一個(gè)函數(shù),并且有兩個(gè)參數(shù)。事實(shí)上就是這樣,返回值是一個(gè),是被加數(shù),是加數(shù)。
源碼注釋版
這一組函數(shù)都是數(shù)學(xué)計(jì)算相關(guān)的,主要分為三類:
加減乘除:add、subtract、multiply、divide
求最大最小平均值:max、maxBy、min、minBy、sum、sumBy、mean、meanBy
小數(shù)的四舍五入:ceil、floor、round
加減乘除在加減乘除的源碼中可以看到這四個(gè)函數(shù)都引用了一個(gè) createMathOpeartion 這個(gè)函數(shù),然后是這樣使用這個(gè)函數(shù)的:
// 加法 const add = createMathOperation((augend, addend) => augend + addend, 0) // 減法 const subtract = createMathOperation((minuend, subtrahend) => minuend - subtrahend, 0) // 乘法 const multiply = createMathOperation((multiplier, multiplicand) => multiplier * multiplicand, 1) // 除法 const divide = createMathOperation((dividend, divisor) => dividend / divisor, 1)
可以發(fā)現(xiàn),它們的實(shí)現(xiàn)方式都是一樣的,向 createMathOperation 傳遞一個(gè)函數(shù),這個(gè)函數(shù)就是原生的加減乘除,所以主要的還是要看看 createMathOperation 是啥。
createMathOperation源碼注釋版
/** * Creates a function that performs a mathematical operation on two values. * * @private * @param {Function} operator The function to perform the operation. * @param {number} [defaultValue] The value used for `undefined` arguments. * @returns {Function} Returns the new mathematical operation function. */
從這個(gè)函數(shù)說(shuō)明中可以看出,這個(gè)函數(shù)有兩個(gè)參數(shù):
operator:原生四則運(yùn)算函數(shù)
defaultValue:默認(rèn)值,當(dāng)未傳遞參數(shù)時(shí)返回的(原生計(jì)算中一般返回 NaN)
我們拿 add 來(lái)舉例。
const add = createMathOperation((augend, addend) => augend + addend, 0) const result = add(5, 3) console.log(result) // 8
首先是通過(guò) createMathOperation 創(chuàng)建一個(gè) add 函數(shù),然后向其傳遞參與計(jì)算的值,也就是說(shuō) createMathOperation 應(yīng)該是返回一個(gè)函數(shù),并且有兩個(gè)參數(shù)。事實(shí)上就是這樣,返回值是一個(gè) function(value, other),value 是被加數(shù),other 是加數(shù)。
在進(jìn)行加減乘除運(yùn)算的時(shí)候,還需要考慮一點(diǎn)的就是參與計(jì)算的兩個(gè)值的數(shù)據(jù)類型,是字符串還是數(shù)字?或者是 undefined?這里的實(shí)現(xiàn)方法滿足以下幾個(gè)規(guī)則:
兩個(gè)值都為 undefined 時(shí),返回 defaultValue
其中一個(gè)值為 undefined 時(shí),返回另一個(gè)值
有一個(gè)值為字符串時(shí),用 baseToString 將兩個(gè)值都轉(zhuǎn)換成 string 進(jìn)行計(jì)算
其它情況,用 baseToNumber 將兩個(gè)值都轉(zhuǎn)換成 number 進(jìn)行計(jì)算
undefined 和 null 在四則運(yùn)算中的區(qū)別我注意到代碼中是判斷 value === undefined,是 ===,說(shuō)明這里嚴(yán)格區(qū)分 undefined 和 null ,這是之前沒(méi)注意到的地方。這是為什么呢?
我拿原生的加減乘除做了個(gè)實(shí)驗(yàn):
console.log(1 + undefined) // NaN console.log(1 + null) // 1 console.log(1 - undefined) // NaN console.log(1 - null) // 1 console.log(1 * undefined) // NaN console.log(1 * null) // 0 console.log(1 / undefined) // NaN console.log(1 / null) // Infinity
undefined 參與計(jì)算的結(jié)果都是 NaN,null 參與計(jì)算是將它看作 0。
嗯,我們不一樣,每個(gè)人都有不同的境遇 ~
But,why?為啥我們不一樣?
我們知道 undefined 和 null 其中有一個(gè)區(qū)別是:
undefined 是定義了但是沒(méi)有賦值
null 是為定義
如果按照這個(gè)區(qū)別,應(yīng)該把 undefined 當(dāng)作 0 啊,但是結(jié)果貌似不是這樣,查查規(guī)范咯
在這就看得比較清楚了,ToNumber 運(yùn)算符會(huì)將 undefined 轉(zhuǎn)換成 NaN,而將 null 轉(zhuǎn)換成 +0。
baseToString源碼注釋版
/** * The base implementation of `toString` which doesn"t convert nullish * values to empty strings. * * @private * @param {*} value The value to process. * @returns {string} Returns the string. */
規(guī)則:
如果 typeof 返回 string,則直接返回 value
如果是數(shù)組,則遞歸對(duì)數(shù)組中的每一項(xiàng)都執(zhí)行 baseToString,直到不是數(shù)組為止,返回的是一個(gè)不含 [] 的字符串,相當(dāng)于 [].join("") 的結(jié)果
如果 isSymbol 判斷為 true,則用 toString.call 來(lái)轉(zhuǎn)換
其它情況,就直接用模板字符串的方式返回字符串
對(duì)于 isSymbol,感覺(jué)還沒(méi)理解到位,先不展開(kāi)說(shuō)了。。。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/90035.html
摘要:原文首發(fā)于源碼講解這是我們閱讀源碼的第篇博客,在這篇文章里我們來(lái)學(xué)習(xí)一下的方法。好啦,關(guān)于函數(shù)暫時(shí)就先講到這里啦。與惡龍纏斗過(guò)久自身亦成為惡龍凝視深淵過(guò)久深淵將回以凝視。 原文首發(fā)于Lodash源碼講解 這是我們閱讀Lodash源碼的第2篇博客,在這篇文章里我們來(lái)學(xué)習(xí)一下Lodash的chunk方法。 chunk函數(shù)內(nèi)部依賴其他的函數(shù),依賴的函數(shù)如下所示; slice 按照慣例,我們先...
摘要:同時(shí),這里會(huì)設(shè)置一個(gè)定時(shí)器,在等待后會(huì)執(zhí)行,的主要作用就是觸發(fā)。最后,如果不再有函數(shù)調(diào)用,就會(huì)在定時(shí)器結(jié)束時(shí)執(zhí)行。問(wèn)題就出在對(duì)于定時(shí)器的控制上。 本文同步自我的Blog 前段時(shí)間團(tuán)隊(duì)內(nèi)部搞了一個(gè)代碼訓(xùn)練營(yíng),大家組織在一起實(shí)現(xiàn) lodash 的 throttle 和 debounce,實(shí)現(xiàn)起來(lái)覺(jué)得并不麻煩,但是最后和官方的一對(duì)比,發(fā)現(xiàn)功能的實(shí)現(xiàn)上還是有差距的,為了尋找我的問(wèn)題,把官方源碼...
摘要:萬(wàn)條數(shù)據(jù)依賴讀源碼之從看稀疏數(shù)組與密集數(shù)組原理的原理歸結(jié)起來(lái)就是切割和放置。尺在切割之前,需要用尺確定切割的數(shù)量。容器的長(zhǎng)度剛好與塊的數(shù)量一致。當(dāng)與塊的數(shù)量相等時(shí),表示已經(jīng)切割完畢,停止切割,最后將結(jié)果返回。 以不正義開(kāi)始的事情,必須用罪惡使它鞏固。——莎士比亞《麥克白》 最近很多事似乎印證了這句話,一句謊言最后要用一百句謊言來(lái)圓謊。 本文為讀 lodash 源碼的第二篇,后續(xù)文章會(huì)...
摘要:而這個(gè)秒就能理解的代碼片段,摒棄了許多不必要的代碼,只實(shí)現(xiàn)了最核心的部分,不像和那樣,考慮參數(shù)邊界值問(wèn)題,例如,參數(shù)的類型是否符合預(yù)期等。使用根據(jù)斷言函數(shù)對(duì)數(shù)組進(jìn)行過(guò)濾,返回條件為真值的對(duì)象。 之前翻譯過(guò)一篇文章,《我喜歡的5個(gè)編程技巧》,里面的一個(gè)技巧是借鑒一個(gè)網(wǎng)站的代碼片段,好奇的小手點(diǎn)下鏈接后,發(fā)現(xiàn)是一個(gè)有 47000 多star的倉(cāng)庫(kù),30-seconds-of-code。 倉(cāng)...
摘要:今天要講的,是我從的源碼實(shí)現(xiàn)文件中學(xué)到的幾個(gè)很基礎(chǔ),卻又容易被忽略的知識(shí)點(diǎn)。在函數(shù)式編程中,函數(shù)是一等公民,它可以只是根據(jù)參數(shù),做簡(jiǎn)單的組合操作,再作為別的函數(shù)的返回值。所以,閱讀源碼,是一種很棒的重溫基礎(chǔ)知識(shí)的方式。 showImg(https://segmentfault.com/img/bVbpTSY?w=750&h=422); 前言 上一篇文章 「前端面試題系列8」數(shù)組去重(1...
閱讀 3176·2021-09-27 13:35
閱讀 723·2021-09-23 11:22
閱讀 2985·2019-08-30 15:54
閱讀 1727·2019-08-29 16:27
閱讀 2562·2019-08-29 15:05
閱讀 2444·2019-08-23 18:11
閱讀 3606·2019-08-23 16:32
閱讀 3015·2019-08-23 14:56