最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Javascript函數(shù)技巧學(xué)習(xí)

 更新時(shí)間:2022年07月29日 09:04:23   作者:? 天行無(wú)忌  ?  
這篇文章主要介紹了Javascript函數(shù)技巧學(xué)習(xí),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下

前言

閱讀代碼是提高編碼水平的好方法,優(yōu)秀的源代碼就像一部文學(xué)巨作,開拓思維,提供啟示。最近在閱讀vue2的源代碼,學(xué)到了很多JS的編碼技巧,后續(xù)陸續(xù)分享出來(lái)供參考,順便總結(jié)一下代碼閱讀成果。

1. 緩存函數(shù)

先來(lái)看一個(gè)需求,假設(shè)有一個(gè)邏輯復(fù)雜的函數(shù) superComputed 執(zhí)行很費(fèi)時(shí)間,如果每次使用都去計(jì)算一次,就會(huì)給用戶帶來(lái)很長(zhǎng)的等待。這個(gè)時(shí)候需要考慮將計(jì)算結(jié)果緩存起來(lái)供后續(xù)程序調(diào)用,緩存函數(shù)需要實(shí)現(xiàn)當(dāng)參數(shù)相同的情況下,直接取緩存結(jié)果。這跟服務(wù)器端為避免過(guò)多的查詢數(shù)據(jù)庫(kù)而用文件緩存查詢結(jié)果相似,在前端如何實(shí)現(xiàn)呢?

const superComputed = (str) => {
    // 假設(shè)這個(gè)函數(shù)執(zhí)行時(shí)間很長(zhǎng)
    console.info("===> 超級(jí)計(jì)算開始了……");
    return `輸入:${str}`;
};

編寫一個(gè) cached 函數(shù)來(lái)封裝目標(biāo)函數(shù),這個(gè) cached 函數(shù)接受目標(biāo)函數(shù)作為參數(shù),然后返回一個(gè)封裝好的新函數(shù)。在 cached 函數(shù)的內(nèi)部,可以使用 Object 或 Map 緩存前一個(gè)函數(shù)調(diào)用的結(jié)果。

vue/src/shared/util.js

這個(gè) cached 的代碼如下:

/**
 * Create a cached version of a pure function.
 */
export function cached<F: Function>(fn: F): F {
    const cache = Object.create(null);
    return (function cachedFn(str: string) {
        const hit = cache[str];
        return hit || (cache[str] = fn(str));
    }: any);
}

現(xiàn)在將 cached 稍微改下,讓其可以執(zhí)行,每次執(zhí)行 superComputed 函數(shù)都會(huì)打印 ===> 超級(jí)計(jì)算開始了……,以方便查看函數(shù)是否被緩存,

如下:

const superComputed = (str) => {
    // 假設(shè)這個(gè)函數(shù)執(zhí)行時(shí)間很長(zhǎng)
    console.info("===> 超級(jí)計(jì)算開始了……");
    return `輸入:${str}`;
};
const cached = (fn) => {
    const cache = Object.create(null);
    return (str) => {
        const hit = cache[str];
        return hit || (cache[str] = fn(str));
    };
};
const cacheSuperComputed = cached(superComputed);
console.log(cacheSuperComputed("DevPoint"));
console.log(cacheSuperComputed("DevPoint"));
console.log(cacheSuperComputed("juejin"));

執(zhí)行后的結(jié)果如下:

===> 超級(jí)計(jì)算開始了……
輸入:DevPoint
輸入:DevPoint
===> 超級(jí)計(jì)算開始了……
輸入:juejin

從結(jié)果不難看出,函數(shù)執(zhí)行結(jié)果在參數(shù)不變的情況下,取得緩存的數(shù)據(jù)。

2. 將dev-point轉(zhuǎn)換為devPoint

在項(xiàng)目開發(fā)過(guò)程中,通常會(huì)出現(xiàn)變量風(fēng)格不一致的問(wèn)題,可以編寫一個(gè)函數(shù)將其轉(zhuǎn)換為統(tǒng)一的風(fēng)格。

vue/src/shared/util.js
/**
 * Camelize a hyphen-delimited string.
 */
const camelizeRE = /-(\w)/g
export const camelize = cached((str: string): string => {
  return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
})

將其稍微修改,里面的 cached 函數(shù)就是之前介紹的緩存函數(shù)。

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

console.log(camelize("dev-point")); // devPoint

3. 自定義函數(shù)判斷

這里所說(shuō)的自定義函數(shù),指的是開發(fā)人員自定義的函數(shù),不是Javascript原生宿主函數(shù)??赡芟氲皆砭褪菍⒑瘮?shù)轉(zhuǎn)換為字符串,先來(lái)看下結(jié)果:

console.log(cached.toString());
console.log(toString.toString());

執(zhí)行結(jié)果如下:

// 下面是自定義函數(shù)的結(jié)果
(fn) => {
    const cache = Object.create(null);
    return (str) => {
        const hit = cache[str];
        return hit || (cache[str] = fn(str));
    };
}
// 下面是原生宿主函數(shù)的結(jié)果
function toString() { [native code] }  

從執(zhí)行結(jié)果來(lái)看,原生宿主函數(shù) toString 的結(jié)果始終是 function fnName() { [native code] } 格式,因此就可以通過(guò)這個(gè)來(lái)區(qū)分,接下來(lái)看看VUE項(xiàng)目中的實(shí)現(xiàn)方式。

vue/src/core/util/env.js

在文件的第 58 行,代碼如下:

/* istanbul ignore next */
export function isNative (Ctor: any): boolean {
  return typeof Ctor === 'function' && /native code/.test(Ctor.toString())
}

4. JS運(yùn)行環(huán)境

在前端快速發(fā)展的今天, JavaScript 代碼可以在不同的運(yùn)行環(huán)境中執(zhí)行。為了更好的適應(yīng)各種運(yùn)行環(huán)境,需要判斷當(dāng)前代碼是在哪個(gè)運(yùn)行環(huán)境中執(zhí)行的,下面來(lái)學(xué)習(xí)一下Vue是如何判斷運(yùn)行環(huán)境的:

vue/src/core/util/env.js

在文件的第 6 行開始,代碼如下:

// Browser environment sniffing
export const inBrowser = typeof window !== 'undefined'
export const inWeex = typeof WXEnvironment !== 'undefined' && !!WXEnvironment.platform
export const weexPlatform = inWeex && WXEnvironment.platform.toLowerCase()
export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
export const isIE = UA && /msie|trident/.test(UA)
export const isIE9 = UA && UA.indexOf('msie 9.0') > 0
export const isEdge = UA && UA.indexOf('edge/') > 0
export const isAndroid = (UA && UA.indexOf('android') > 0) || (weexPlatform === 'android')
export const isIOS = (UA && /iphone|ipad|ipod|ios/.test(UA)) || (weexPlatform === 'ios')
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
export const isPhantomJS = UA && /phantomjs/.test(UA)
export const isFF = UA && UA.match(/firefox\/(\d+)/)

這些判斷代碼都值得借鑒的,這里不展開介紹了,之前在《4個(gè)值得收藏的Javascript技巧》介紹了瀏覽器的判斷。

到此這篇關(guān)于Javascript函數(shù)技巧學(xué)習(xí)的文章就介紹到這了,更多相關(guān)Javascript技巧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

南昌县| 麦盖提县| 禄丰县| 太仆寺旗| 分宜县| 延寿县| 阳高县| 祁门县| 拉孜县| 大兴区| 阿荣旗| 磴口县| 平度市| 漳州市| 云梦县| 扬州市| 凌海市| 广灵县| 四会市| 浦江县| 大同市| 卫辉市| 宜川县| 桐庐县| 永登县| 马公市| 麻城市| 阿图什市| 松阳县| 石棉县| 克什克腾旗| 修水县| 元朗区| 蓝田县| 河东区| 靖安县| 合肥市| 大石桥市| 抚州市| 山阴县| 湖南省|