摘要:寫了幾篇筆記以后發(fā)現(xiàn)很多函數(shù)大量依賴了內(nèi)部的基礎(chǔ)函數(shù),一次性讀完有點麻煩,所以還是決定從基礎(chǔ)函數(shù)沒有或者很少依賴其他函數(shù)看起。
百忙之中(閑來無事)想抽點時間好好讀一下源碼,于是就選了Lodash來寫一個系列罷。寫了幾篇筆記以后發(fā)現(xiàn)很多函數(shù)大量依賴了內(nèi)部的基礎(chǔ)函數(shù),一次性讀完有點麻煩,所以還是決定從基礎(chǔ)函數(shù)(沒有或者很少依賴其他函數(shù))看起。
文檔地址:中文文檔?? 英文文檔
源碼地址:gayhub
baseGetTag,判斷變量類型。因為typeof在面對new Number(1)這種情況時力有不逮,所以lodash重寫了類型判斷。 javascript秘密花園中也提到了JavaScript 標(biāo)準(zhǔn)庫 推薦的是Object.prototype.toString.call(value)這種方式來判斷類型,不過lodash明顯做的更多,前半段是推薦的方式,后半段目測是針對Symbol類型做了優(yōu)化,具體步驟待研究,有了解的同學(xué)歡迎告訴我。
const objectProto = Object.prototype const hasOwnProperty = objectProto.hasOwnProperty const toString = objectProto.toString const symToStringTag = typeof Symbol != "undefined" ? Symbol.toStringTag : undefined function baseGetTag(value) { if (value == null) { return value === undefined ? "[object Undefined]" : "[object Null]" } if (!(symToStringTag && symToStringTag in Object(value))) { return toString.call(value) } const isOwn = hasOwnProperty.call(value, symToStringTag) const tag = value[symToStringTag] let unmasked = false try { value[symToStringTag] = undefined unmasked = true } catch (e) {} const result = toString.call(value) if (unmasked) { if (isOwn) { value[symToStringTag] = tag } else { delete value[symToStringTag] } } return result } export default baseGetTaggetTag
getTag是在baseGetTag基礎(chǔ)上的包裝,主要是為了兼容IE 11中的 data views, maps, sets, weak maps 和當(dāng)Node.js < 6時的promises,這一點在源碼注釋中已有體現(xiàn)
import baseGetTag from "./baseGetTag.js" /** `Object#toString` result references. */ const dataViewTag = "[object DataView]" const mapTag = "[object Map]" const objectTag = "[object Object]" const promiseTag = "[object Promise]" const setTag = "[object Set]" const weakMapTag = "[object WeakMap]" /** Used to detect maps, sets, and weakmaps. */ const dataViewCtorString = `${DataView}` const mapCtorString = `${Map}` const promiseCtorString = `${Promise}` const setCtorString = `${Set}` const weakMapCtorString = `${WeakMap}` let getTag = baseGetTag // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in // Node.js < 6. if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || (getTag(new Map) != mapTag) || (getTag(Promise.resolve()) != promiseTag) || (getTag(new Set) != setTag) || (getTag(new WeakMap) != weakMapTag)) { getTag = (value) => { const result = baseGetTag(value) const Ctor = result == objectTag ? value.constructor : undefined const ctorString = Ctor ? `${Ctor}` : "" if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag case mapCtorString: return mapTag case promiseCtorString: return promiseTag case setCtorString: return setTag case weakMapCtorString: return weakMapTag } } return result } } export default getTagisObjectLike
isObjectLike, 判斷是否是一個對象
function isObjectLike(value) { return typeof value == "object" && value !== null } export default isObjectLikeisArguments
isArguments調(diào)用了getTag和isObjectLike用來判斷參數(shù)是否是一個Arguments對象。
import getTag from "./.internal/getTag.js" import isObjectLike from "./isObjectLike" function isArguments(value) { return isObjectLike(value) && getTag(value) == "[object Arguments]" } export default isArgumentsisFlattenable
isFlattenable調(diào)用isArguments來判斷是否為一個Arguments對象或數(shù)組或是一個能展開的Symbol
import isArguments from "../isArguments.js" const spreadableSymbol = Symbol.isConcatSpreadable function isFlattenable(value) { return Array.isArray(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]) } export default isFlattenablebaseFlatten
baseFlatten可以展開數(shù)組的n層嵌套(扁平處理),依賴了isFlattenable
// 例: baseFlatten([[[1,2,3],[2,2,3]],4,5,6], 2) // => [1, 2, 3, 2, 2, 3, 4, 5, 6] // isStrict == true baseFlatten([[1,2,3],[2,2,3],4,5,6], 1, null, true) // => [1, 2, 3, 2, 2, 3]
import isFlattenable from "./isFlattenable.js" function baseFlatten(array, depth, predicate, isStrict, result) { predicate || (predicate = isFlattenable) // predicate參數(shù)兜底 result || (result = []) // 返回新數(shù)組 if (array == null) { return result } // 遞歸調(diào)用本身,嚴(yán)格模式`isStrict = true`直接退出循環(huán) for (const value of array) { if (depth > 0 && predicate(value)) { if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). baseFlatten(value, depth - 1, predicate, isStrict, result) } else { result.push(...value) } } else if (!isStrict) { result[result.length] = value } } return result } export default baseFlattenisLength
isLength,判斷是否是一個有效數(shù)字
const MAX_SAFE_INTEGER = 9007199254740991 // 最大數(shù) function isLength(value) { // type是number并且大于等于0且小于等于最大數(shù) return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER } export default isLengthisArrayLike
isArrayLike, 判斷是否是一個數(shù)組,依賴了isLength
import isLength from "./isLength.js" function isArrayLike(value) { // value不為空,不是function且有l(wèi)ength屬性 return value != null && typeof value != "function" && isLength(value.length) } export default isArrayLikeisArrayLikeObject
isArrayLikeObject,判斷是否是一個數(shù)組或者對象,依賴了isArrayLike和isObjectLike
import isArrayLike from "./isArrayLike.js" import isObjectLike from "./isObjectLike.js" function isArrayLikeObject(value) { return isObjectLike(value) && isArrayLike(value) } export default isArrayLikeObjecteq
eq,判斷兩個值是否相等。
function eq(value, other) { return value === other || (value !== value && other !== other) } export default eq
||前面好理解,判斷兩個值全等
||后面是為了判斷 NaN
例:
const object = { "a": 1 } const other = { "a": 1 } eq(object, object) // => true eq(object, other) // => false eq("a", "a") // => true eq("a", Object("a")) // => false eq(NaN, NaN) // => trueassocIndexOf
獲取鍵值對數(shù)組中的“鍵”的索引。例:
assocIndexOf([[1,2],[3,4],[5,6]], 2) // => -1 assocIndexOf([[1,2],[3,4],[5,6]], 3) // => 1
import eq from "../eq.js" function assocIndexOf(array, key) { let { length } = array while (length--) { if (eq(array[length][0], key)) { return length } } return -1 } export default assocIndexOf
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/93536.html
摘要:是函數(shù)柯里化的函數(shù)。例子柯里化有個常見作用參數(shù)復(fù)用構(gòu)建高階函數(shù)延遲計算。是的,它其實就是柯里化的具體應(yīng)用構(gòu)建高階函數(shù)。這個是我認(rèn)為的中最有意思的方法。不過要注意最后的。這同樣是用來組合高階函數(shù)的一個方法。 最近在學(xué)習(xí)JS函數(shù)式編程相關(guān)的內(nèi)容,于是詳細的翻看了Lodash的文檔,感到別有洞天。這里把自己對一些API的使用和看法做個筆記記錄下。 Array _.head/_.last 例子...
摘要:例如現(xiàn)在的入門學(xué)習(xí)手記系列。收到粉絲留言和打賞的喜悅。安裝上一篇入門學(xué)習(xí)手記一,主要是介紹了的核心概念,是整個學(xué)習(xí)過程的基礎(chǔ)知識。新生成的類似如下入門學(xué)習(xí)手記因為生成的內(nèi)容過多,我直接省略掉了。 showImg(https://segmentfault.com/img/bVbk5Nd?w=1150&h=599); 本人微信公眾號:前端修煉之路,歡迎關(guān)注。 最近開始想要維護一個個人的公眾...
摘要:文檔地址中文文檔英文文檔源碼地址將數(shù)組拆分成多個長度的區(qū)塊,并將這些區(qū)塊組成一個新數(shù)組。如果無法被分割成全部等長的區(qū)塊,那么最后剩余的元素將組成一個區(qū)塊。 百忙之中(閑來無事)想抽點時間好好讀一下源碼,于是就選了Lodash來寫一個系列罷。讀源碼順序就按照loadsh文檔順序來。 文檔地址:中文文檔?? 英文文檔源碼地址:gayhub _.chunk(array, [size...
摘要:文檔地址中文文檔英文文檔源碼地址創(chuàng)建一個新數(shù)組,包含原數(shù)組中所有的非假值元素。例如和都是被認(rèn)為是假值。下面對比一下兩者效率,如下圖傳送門可以看到使用更快,如果沒有兼容性需求,還是使用原生函數(shù)比較好。 百忙之中(閑來無事)想抽點時間好好讀一下源碼,于是就選了Lodash來寫一個系列罷。讀源碼順序就按照loadsh文檔順序來。 文檔地址:中文文檔?? 英文文檔源碼地址:gayhub ...
摘要:文檔地址中文文檔英文文檔源碼地址第一個函數(shù)是,不過源碼中依賴了,所以第一篇文章就從開始。這個函數(shù)的作用就是裁剪數(shù)組,從下標(biāo)開始,到下標(biāo)結(jié)束,但是并不包含,并將結(jié)果作為一個數(shù)組返回。并且注明了這個方法用于代替來確保數(shù)組正確返回。 百忙之中(閑來無事)想抽點時間好好讀一下源碼,于是就選了Lodash來寫一個系列罷。讀源碼順序就按照loadsh文檔順序來。 文檔地址:中文文檔?? 英文文檔源...
閱讀 462·2023-04-25 23:00
閱讀 3493·2021-11-22 13:54
閱讀 1892·2021-10-27 14:14
閱讀 1485·2019-08-30 13:59
閱讀 3510·2019-08-23 16:15
閱讀 1957·2019-08-23 16:06
閱讀 3326·2019-08-23 15:26
閱讀 1256·2019-08-23 13:48