91aaa在线国内观看,亚洲AV午夜福利精品一区二区,久久偷拍人视频,久久播这里有免费视播

<strong id="fvuar"></strong>

  • <sub id="fvuar"><dl id="fvuar"><em id="fvuar"></em></dl></sub>

    1. 千鋒教育-做有情懷、有良心、有品質(zhì)的職業(yè)教育機(jī)構(gòu)

      手機(jī)站
      千鋒教育

      千鋒學(xué)習(xí)站 | 隨時(shí)隨地免費(fèi)學(xué)

      千鋒教育

      掃一掃進(jìn)入千鋒手機(jī)站

      領(lǐng)取全套視頻
      千鋒教育

      關(guān)注千鋒學(xué)習(xí)站小程序
      隨時(shí)隨地免費(fèi)學(xué)習(xí)課程

      當(dāng)前位置:首頁(yè)  >  技術(shù)干貨  > 22個(gè)Vue源碼中的工具函數(shù)

      22個(gè)Vue源碼中的工具函數(shù)

      來(lái)源:千鋒教育
      發(fā)布人:qyf
      時(shí)間: 2023-01-17 16:50:00 1673945400

      22個(gè) Vue 源碼中的工具函數(shù)

        前言

        在 vue 源碼中,封裝了很多工具函數(shù),學(xué)習(xí)這些函數(shù),一方面學(xué)習(xí)大佬們的實(shí)現(xiàn)方式,另一方面是溫習(xí)基礎(chǔ)知識(shí),希望大家在日常工作中,簡(jiǎn)單的函數(shù)也可以自己封裝,提高編碼能力。

        本次涉及的工具函數(shù) 1-16 在 Vue3 的源碼中,路徑是 core/packages/shared/src/index.ts。

        17-22 在 Vue2 的源碼中,路徑是 vue/src/shared/util.ts。

        1、 EMPTY_OBJ 空對(duì)象

        const EMPTY_OBJ = __DEV__

        ? Object.freeze({})

        : {}

        注意:

        Object.freeze 只能淺凍結(jié),如果屬性是對(duì)象,對(duì)屬性的屬性的修改就無(wú)法凍結(jié)了

        const obj = { name: '張三', info: { a: 1, b: 2

        }

        };Object.freeze(obj);obj.name = '李四';console.log(obj); // { name: '張三', info: { a: 1, b: 2 } }obj.info.a = 66;console.log(obj); // { name: '張三', info: { a: 66, b: 2 } }

        源碼中的使用:

      圖片 1

        可以看出基本都是作為初始化或者兜底使用,由此產(chǎn)生疑問(wèn):

        · 使用的地方有的是 options,有的是 props,不同地方用同一個(gè)對(duì)象,不會(huì)有問(wèn)題么?

        首先,很多初始化操作,后續(xù)都會(huì)重新賦值,EMPTY_OBJ 只是作為占位使用。其次,因?yàn)?Object.freeze 的原因,無(wú)法修改 EMPTY_OBJ,所以任何引用這個(gè)對(duì)象的地方,都不會(huì)受到影響。

        · 為什么判斷是 __DEV__(process.env.NODE_ENV !== 'production') 的時(shí)候才使用 Object.freeze?

        Object.freeze 更多的是 Vue 源碼開(kāi)發(fā)者在調(diào)試時(shí)使用,可以通過(guò)報(bào)錯(cuò),防止對(duì)空對(duì)象操作,更快發(fā)現(xiàn)源碼問(wèn)題。也因此,開(kāi)發(fā)環(huán)境最終會(huì)避免了對(duì) EMPTY_OBJ 的賦值操作,所以在生產(chǎn)環(huán)境使用 Object.freeze 意義不大。

        2、EMPTY_ARR 空數(shù)組

        const EMPTY_ARR = __DEV__ ? Object.freeze([]) : []

        3、 NOOP 空函數(shù)

        const NOOP = () => {}

        依舊作為兜底和占位使用:

      圖片 2

        4、 NO 永遠(yuǎn)返回 false 的函數(shù)

        const NO = () => false

        源碼中的使用:

      圖片 3

      圖片 4

        5、isOn 判斷字符串是不是 on 開(kāi)頭,并且 on 后首字母不是小寫(xiě)字母

        const onRE = /^on[^a-z]/;const isOn = (key) => onRE.test(key);// 示例isOn('onChange'); // trueisOn('onchange'); // falseisOn('on3change'); // true

        6、類型判斷

        const isArray = Array.isArray

        const isFunction = (val) => typeof val === 'function'const isString = (val) => typeof val === 'string'const isSymbol = (val) => typeof val === 'symbol'const isObject = (val) => val !== null && typeof val === 'object'const toTypeString = (value) => Object.prototype.toString.call(value)

        const isMap = (val) => toTypeString(val) === '[object Map]'const isSet = (val) => toTypeString(val) === '[object Set]'const isDate = (val) => toTypeString(val) === '[object Date]'const isPlainObject = (val) => Object.prototype.toString.call(val) === '[object Object]'// isPlainObject 判斷是不是普通對(duì)象(排除正則、數(shù)組、日期、new Boolean、new Number、new String 這些特殊的對(duì)象)

        isObject([]) // trueisPlainObject([]) // falseconst isPromise = (val) => { return isObject(val) && isFunction(val.then) && isFunction(val.catch)

        }

        7、 toRawType 提取數(shù)據(jù)原始類型

        const toRawType = (value) => { return Object.prototype.toString.call(value).slice(8, -1)

        }// 示例toRawType(''); 'String'toRawType([]); 'Array'

        源碼中的使用:

      圖片 5

        8、isIntegerKey 判斷是不是數(shù)字型的字符串

        const isIntegerKey = (key) => isString(key) &&

        key !== 'NaN' &&

        key[0] !== '-' && '' + parseInt(key, 10) === key;

        // 例子:

        isIntegerKey('a'); // falseisIntegerKey('0'); // trueisIntegerKey('011'); // falseisIntegerKey('11'); // trueisIntegerKey('-11'); // falseisIntegerKey(11); // falseisIntegerKey('NaN'); // false

        9、makeMap 將字符串分隔成 map,區(qū)分大小寫(xiě),返回一個(gè)函數(shù)來(lái)判斷 map 中是否含有某個(gè) key

        function makeMap(str, expectsLowerCase) { const map = Object.create(null); const list = str.split(','); for (let i = 0; i < list.length; i++) {

        map[list[i]] = true;

        } return expectsLowerCase ? val => !!map[val.toLowerCase()] : val => !!map[val];

        }

        10、isReservedProp 是否是保留屬性

        const isReservedProp = /*#__PURE__*/ makeMap(// the leading comma is intentional so empty string "" is also included',key,ref,ref_for,ref_key,' + 'onVnodeBeforeMount,onVnodeMounted,' + 'onVnodeBeforeUpdate,onVnodeUpdated,' + 'onVnodeBeforeUnmount,onVnodeUnmounted');

        // ['', 'key', 'ref', 'ref_for', 'ref_key', 'onVnodeBeforeMount', 'onVnodeMounted', 'onVnodeBeforeUpdate', 'onVnodeUpdated', 'onVnodeBeforeUnmount', 'onVnodeUnmounted']

        // 示例

        isReservedProp('key'); // trueisReservedProp('onVnodeBeforeMount'); // trueisReservedProp(''); // trueisReservedProp(' '); // false

        如果有 /#PURE/ 這個(gè)標(biāo)志,說(shuō)明他是純函數(shù),如果沒(méi)有調(diào)用它,打包工具會(huì)直接通 tree-shaking 把它刪除,減少代碼體積。

        11、 isBuiltInDirective 是否是內(nèi)置指令

        const isBuiltInDirective = /*#__PURE__*/ makeMap( 'bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo'

        )

        12、 cacheStringFunction 將函數(shù)變?yōu)榭删彺娼Y(jié)果的函數(shù)

        const cacheStringFunction = (fn) => { const cache = Object.create(null); return ((str) => { const hit = cache[str]; return hit || (cache[str] = fn(str));

        });

        };

        13、 camelize & hyphenate 連字符與駝峰互轉(zhuǎn)

        const camelizeRE = /-(\w)/g;const camelize = cacheStringFunction((str) => { return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));

        });// 清爽版const camelize = str => str.replace(camelizeRE, (_, c) => { return c ? c.toUpperCase() : '';

        });// 舉例:on-click-a => onClickAcamelize('on-click-a');const hyphenateRE = /\B([A-Z])/g;const hyphenate = cacheStringFunction((str) => str.replace(hyphenateRE, '-$1').toLowerCase());// 清爽版const hyphenate = str => str.replace(hyphenateRE, '-$1').toLowerCase();// 仿照 camelize 寫(xiě)法const hyphenate = str => str.replace(hyphenateRE, (_, c) => { return c ? `-${c.toLowerCase()}` : '';

        });// 舉例:onClickA => on-click-ahyphenate('onClickA');

        14、 hasChanged 判斷是不是有變化

        const hasChanged = (value, oldValue) => value !== oldValue && (value === value || oldValue === oldValue);// 示例

        hasChanged(1, 1); // falsehasChanged(1, 2); // truehasChanged(+0, -0); // falsehasChanged(NaN, NaN); // false// 場(chǎng)景:watch 監(jiān)測(cè)值是不是變化了// 擴(kuò)展 Object.is & ===Object.is(+0, -0); // false Object.is(NaN, NaN); // true+0 === -0 // trueNaN === NaN // false

        15、invokeArrayFns 執(zhí)行數(shù)組里的函數(shù)

        const invokeArrayFns = (fns, arg) => { for (let i = 0; i < fns.length; i++) {

        fns[i](arg);

        }

        };// 示例const arr = [ function(val){ console.log(val + '張三');

        }, function(val){ console.log(val + '李四');

        }, function(val){ console.log(val + '王五');

        },

        ]

        invokeArrayFns(arr, '我是:');

        源碼中的使用:

      圖片 6

        16、 toNumber 轉(zhuǎn)數(shù)字

        const toNumber = (val) => {

        const n = parseFloat(val); return isNaN(n) ? val : n;

        };

        toNumber('111'); // 111toNumber('a111'); // 'a111'toNumber('11a11'); // '11'toNumber(NaN); // NaN// isNaN vs Number.isNaN// isNaN 判斷是不是數(shù)字 is Not a Number// Number.isNaN 判斷是不是 NaNisNaN(NaN); // trueisNaN('a'); // trueNumber.isNaN(NaN); // trueNumber.isNaN('a'); // false// Number.isNaN 的 polyfillif (!Number.isNaN) { Number.isNaN = function (n) { // 方法一 return (window.isNaN(n) && typeof n === 'number'); // 方法二 利用只有 NaN 不跟自己相等的特性 return n !== n;

        };

        }

        17、isPrimitive 是否為原始數(shù)據(jù)

        function isPrimitive(value) { return ( typeof value === 'string' || typeof value === 'number' || typeof value === 'symbol' || typeof value === 'boolean'

        )

        }

        18、 isValidArrayIndex 是否為有效的數(shù)組下標(biāo),整數(shù)并且不是無(wú)窮大

        function isValidArrayIndex(val) { const n = parseFloat(String(val)) return n >= 0 && Math.floor(n) === n && isFinite(val)

        }// isFinite 如果參數(shù)是 NaN,正無(wú)窮大或者負(fù)無(wú)窮大,會(huì)返回 false,其他返回 true

        19、bind 能兼容的bind函數(shù)

        function polyfillBind(fn, ctx) { function boundFn(a) { const l = arguments.length return l

        ? l > 1

        ? fn.apply(ctx, arguments)

        : fn.call(ctx, a)

        : fn.call(ctx)

        }

        boundFn._length = fn.length return boundFn

        }function nativeBind(fn, ctx) { return fn.bind(ctx)

        }const bind = Function.prototype.bind ? nativeBind : polyfillBind

        20、 toArray 類數(shù)組轉(zhuǎn)化為數(shù)組

        function toArray(list, start) { start = start || 0

        let i = list.length - start

        const ret = new Array(i) while (i--) {

        ret[i] = list[i + start]

        } return ret

        }

        21、 once 只執(zhí)行一次

        function once(fn) { let called = false

        return function () { if (!called) {

        called = true

        fn.apply(this, arguments)

        }

        }

        }

        22、 isNative 是否為原生系統(tǒng)函數(shù)

        function isNative(Ctor) { return typeof Ctor === 'function' && /native code/.test(Ctor.toString())

        }

        - End -

      tags:
      聲明:本站稿件版權(quán)均屬千鋒教育所有,未經(jīng)許可不得擅自轉(zhuǎn)載。
      10年以上業(yè)內(nèi)強(qiáng)師集結(jié),手把手帶你蛻變精英
      請(qǐng)您保持通訊暢通,專屬學(xué)習(xí)老師24小時(shí)內(nèi)將與您1V1溝通
      免費(fèi)領(lǐng)取
      今日已有369人領(lǐng)取成功
      劉同學(xué) 138****2860 剛剛成功領(lǐng)取
      王同學(xué) 131****2015 剛剛成功領(lǐng)取
      張同學(xué) 133****4652 剛剛成功領(lǐng)取
      李同學(xué) 135****8607 剛剛成功領(lǐng)取
      楊同學(xué) 132****5667 剛剛成功領(lǐng)取
      岳同學(xué) 134****6652 剛剛成功領(lǐng)取
      梁同學(xué) 157****2950 剛剛成功領(lǐng)取
      劉同學(xué) 189****1015 剛剛成功領(lǐng)取
      張同學(xué) 155****4678 剛剛成功領(lǐng)取
      鄒同學(xué) 139****2907 剛剛成功領(lǐng)取
      董同學(xué) 138****2867 剛剛成功領(lǐng)取
      周同學(xué) 136****3602 剛剛成功領(lǐng)取
      相關(guān)推薦HOT
      工業(yè)機(jī)器人、自動(dòng)化、PLC三者是什么關(guān)系?

      一、工業(yè)機(jī)器人和自動(dòng)化工業(yè)機(jī)器人是自動(dòng)化技術(shù)的一部分,是自動(dòng)化生產(chǎn)線的關(guān)鍵組件之一。在自動(dòng)化生產(chǎn)線中,工業(yè)機(jī)器人被廣泛應(yīng)用于執(zhí)行各種任...詳情>>

      2023-10-15 01:41:38
      為什么Redis要對(duì)一種數(shù)據(jù)類型存儲(chǔ)兩次呢?

      一、實(shí)現(xiàn)快速數(shù)據(jù)訪問(wèn)Redis是一種高性能的內(nèi)存數(shù)據(jù)庫(kù),將數(shù)據(jù)存儲(chǔ)在內(nèi)存中可以實(shí)現(xiàn)非??焖俚臄?shù)據(jù)讀取和訪問(wèn)。為了進(jìn)一步提高數(shù)據(jù)的訪問(wèn)速度,R...詳情>>

      2023-10-15 01:40:32
      什么是編程思想?

      一、編程思想的定義和理念編程思想可以理解為一套指導(dǎo)編程活動(dòng)的理念和原則。它包括如何定義問(wèn)題,如何設(shè)計(jì)解決方案,以及如何實(shí)現(xiàn)和測(cè)試這個(gè)解...詳情>>

      2023-10-15 01:22:38
      迭代開(kāi)發(fā)模型中最容易出問(wèn)題的階段是什么?

      一、迭代開(kāi)發(fā)模型中最容易出問(wèn)題的階段是什么 在迭代開(kāi)發(fā)模型中,最容易出問(wèn)題的階段通常是需求收集和分析階段。在這個(gè)階段,開(kāi)發(fā)團(tuán)隊(duì)需要與客...詳情>>

      2023-10-15 01:03:52
      軟件測(cè)試中bug管理工具Jira怎么樣?

      一、Jira是什么 Jira是一款由澳大利亞軟件公司Atlassian開(kāi)發(fā)的項(xiàng)目管理和問(wèn)題跟蹤工具。它是一種用于敏捷項(xiàng)目開(kāi)發(fā)和軟件開(kāi)發(fā)過(guò)程中的工具,廣泛...詳情>>

      2023-10-15 01:02:32
      快速通道