15個工程必備的JavaScript代碼片段(建議添加到項目中)

關(guān)注我不定時分享更多內(nèi)容.
15個工程必備的JavaScript代碼片段扮超,聽過這樣起博客標(biāo)題可以提高閱讀量。??

  1. 獲取文件后綴名
    使用場景:上傳文件判斷后綴名
/**
 * 獲取文件后綴名
 * @param {String} filename
 */
 export function getExt(filename) {
    if (typeof filename == 'string') {
        return filename
            .split('.')
            .pop()
            .toLowerCase()
    } else {
        throw new Error('filename must be a string type')
    }
}

使用方式

getExt("1.mp4") //->mp4
  1. 復(fù)制內(nèi)容到剪貼板
export function copyToBoard(value) {
    const element = document.createElement('textarea')
    document.body.appendChild(element)
    element.value = value
    element.select()
    if (document.execCommand('copy')) {
        document.execCommand('copy')
        document.body.removeChild(element)
        return true
    }
    document.body.removeChild(element)
    return false
}

使用方式:

//如果復(fù)制成功返回true
copyToBoard('lalallala')

原理:

創(chuàng)建一個textare元素并調(diào)用select()方法選中
document.execCommand('copy')方法,拷貝當(dāng)前選中內(nèi)容到剪貼板萤悴。

  1. 休眠多少毫秒
/**
 * 休眠xxxms
 * @param {Number} milliseconds
 */
export function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
}

//使用方式
const fetchData=async()=>{
 await sleep(1000)
}
  1. 生成隨機(jī)字符串
/**
 * 生成隨機(jī)id
 * @param {*} length
 * @param {*} chars
 */
export function uuid(length, chars) {
    chars =
        chars ||
        '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
    length = length || 8
    var result = ''
    for (var i = length; i > 0; --i)
        result += chars[Math.floor(Math.random() * chars.length)]
    return result
}
使用方式

//第一個參數(shù)指定位數(shù)瘾腰,第二個字符串指定字符,都是可選參數(shù)覆履,如果都不傳蹋盆,默認(rèn)生成8位
uuid()  

使用場景:用于前端生成隨機(jī)的ID,畢竟現(xiàn)在的Vue和React都需要綁定key

  1. 簡單的深拷貝
/**
 *深拷貝
 * @export
 * @param {*} obj
 * @returns
 */
export function deepCopy(obj) {
    if (typeof obj != 'object') {
        return obj
    }
    if (obj == null) {
        return obj
    }
    return JSON.parse(JSON.stringify(obj))
}

缺陷:只拷貝對象、數(shù)組以及對象數(shù)組硝全,對于大部分場景已經(jīng)足夠

const person={name:'xiaoming',child:{name:'Jack'}}
deepCopy(person) //new person
  1. 數(shù)組去重
/**
 * 數(shù)組去重
 * @param {*} arr
 */
export function uniqueArray(arr) {
    if (!Array.isArray(arr)) {
        throw new Error('The first parameter must be an array')
    }
    if (arr.length == 1) {
        return arr
    }
    return [...new Set(arr)]
}

原理是利用Set中不能出現(xiàn)重復(fù)元素的特性

uniqueArray([1,1,1,1,1])//[1]
  1. 對象轉(zhuǎn)化為FormData對象
/**
 * 對象轉(zhuǎn)化為formdata
 * @param {Object} object
 */

 export function getFormData(object) {
    const formData = new FormData()
    Object.keys(object).forEach(key => {
        const value = object[key]
        if (Array.isArray(value)) {
            value.forEach((subValue, i) =>
                formData.append(key + `[${i}]`, subValue)
            )
        } else {
            formData.append(key, object[key])
        }
    })
    return formData
}

使用場景:上傳文件時我們要新建一個FormData對象栖雾,然后有多少個參數(shù)就append多少次,使用該函數(shù)可以簡化邏輯

使用方式:

let req={
    file:xxx,
    userId:1,
    phone:'15198763636',
    //...
}
fetch(getFormData(req))

8.保留到小數(shù)點以后n位

// 保留小數(shù)點以后幾位伟众,默認(rèn)2位
export function cutNumber(number, no = 2) {
    if (typeof number != 'number') {
        number = Number(number)
    }
    return Number(number.toFixed(no))
}
  1. 下載一個excel文檔
    同時適用于word,ppt等瀏覽器不會默認(rèn)執(zhí)行預(yù)覽的文檔,也可以用于下載后端接口返回的流數(shù)據(jù)析藕,見11
//下載一個鏈接 
function download(link, name) {
    if(!name){
            name=link.slice(link.lastIndexOf('/') + 1)
    }
    let eleLink = document.createElement('a')
    eleLink.download = name
    eleLink.style.display = 'none'
    eleLink.href = link
    document.body.appendChild(eleLink)
    eleLink.click()
    document.body.removeChild(eleLink)
}
//下載excel
download('http://111.229.14.189/file/1.xlsx')
  1. 在瀏覽器中自定義下載一些內(nèi)容
    場景:我想下載一些DOM內(nèi)容,我想下載一個JSON文件
/**
 * 瀏覽器下載靜態(tài)文件
 * @param {String} name 文件名
 * @param {String} content 文件內(nèi)容
 */
function downloadFile(name, content) {
    if (typeof name == 'undefined') {
        throw new Error('The first parameter name is a must')
    }
    if (typeof content == 'undefined') {
        throw new Error('The second parameter content is a must')
    }
    if (!(content instanceof Blob)) {
        content = new Blob([content])
    }
    const link = URL.createObjectURL(content)
    download(link, name)
}
//下載一個鏈接
function download(link, name) {
    if (!name) {//如果沒有提供名字凳厢,從給的Link中截取最后一坨
        name =  link.slice(link.lastIndexOf('/') + 1)
    }
    let eleLink = document.createElement('a')
    eleLink.download = name
    eleLink.style.display = 'none'
    eleLink.href = link
    document.body.appendChild(eleLink)
    eleLink.click()
    document.body.removeChild(eleLink)
}

使用方式:

downloadFile('1.txt','lalalallalalla')
downloadFile('1.json',JSON.stringify({name:'hahahha'}))
  1. 下載后端返回的流
    數(shù)據(jù)是后端以接口的形式返回的,調(diào)用9中的download方法進(jìn)行下載
 download('http://111.229.14.189/gk-api/util/download?file=1.jpg')
 download('http://111.229.14.189/gk-api/util/download?file=1.mp4')

其他文件流函數(shù)已Excel為例:

function downFileByPost(url, parameter) {
  return axios({
    url: url,
    data: parameter,
    method: 'post',
    responseType: 'blob'
  })
}
function  handleExportXlsByPost(fileName) {
    if (!fileName || typeof fileName !== 'string') {
      fileName = '導(dǎo)出文件'
    }
    let param = {  };
    
    console.log('導(dǎo)出參數(shù)', param)
    downFileByPost(exportXlsUrl, param).then((data) => {
      if (!data) {
        this.$message.warning('文件下載失敗')
        return
      }
      if (typeof window.navigator.msSaveBlob !== 'undefined') {
        window.navigator.msSaveBlob(new Blob([data], { type: 'application/vnd.ms-excel' }), fileName + '.xls')
      } else {
        let url = window.URL.createObjectURL(new Blob([data], { type: 'application/vnd.ms-excel' }))
        let link = document.createElement('a')
        link.style.display = 'none'
        link.href = url
        link.setAttribute('download', fileName + '.xls')
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link); // 下載完成移除元素
        window.URL.revokeObjectURL(url); // 釋放掉blob對象
      }
    })
  }
  1. 提供一個圖片鏈接账胧,點擊下載
    圖片、pdf等文件先紫,瀏覽器會默認(rèn)執(zhí)行預(yù)覽治泥,不能調(diào)用download方法進(jìn)行下載,需要先把圖片遮精、pdf等文件轉(zhuǎn)成blob居夹,再調(diào)用download方法進(jìn)行下載,轉(zhuǎn)換的方式是使用axios請求對應(yīng)的鏈接

//可以用來下載瀏覽器會默認(rèn)預(yù)覽的文件類型本冲,例如mp4,jpg等

import axios from 'axios'
//提供一個link准脂,完成文件下載,link可以是  http://xxx.com/xxx.xls
function downloadByLink(link,fileName){
    axios.request({
        url: link,
        responseType: 'blob' //關(guān)鍵代碼檬洞,讓axios把響應(yīng)改成blob
    }).then(res => {
 const link=URL.createObjectURL(res.data)
        download(link, fileName)
    })

}

注意:會有同源策略的限制意狠,需要配置轉(zhuǎn)發(fā)
  1. 防抖
    在一定時間間隔內(nèi),多次調(diào)用一個方法疮胖,只會執(zhí)行一次.

這個方法的實現(xiàn)是從Lodash庫中copy的

/**
 *
 * @param {*} func 要進(jìn)行debouce的函數(shù)
 * @param {*} wait 等待時間,默認(rèn)500ms
 * @param {*} immediate 是否立即執(zhí)行
 */
export function debounce(func, wait=500, immediate=false) {
    var timeout
    return function() {
        var context = this
        var args = arguments

        if (timeout) clearTimeout(timeout)
        if (immediate) {
            // 如果已經(jīng)執(zhí)行過环戈,不再執(zhí)行
            var callNow = !timeout
            timeout = setTimeout(function() {
                timeout = null
            }, wait)
            if (callNow) func.apply(context, args)
        } else {
            timeout = setTimeout(function() {
                func.apply(context, args)
            }, wait)
        }
    }
}

使用方式:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <input id="input" />
        <script>
            function onInput() {
                console.log('1111')
            }
            const debounceOnInput = debounce(onInput)
            document
                .getElementById('input')
                .addEventListener('input', debounceOnInput) //在Input中輸入闷板,多次調(diào)用只會在調(diào)用結(jié)束之后,等待500ms觸發(fā)一次   
        </script>
    </body>
</html>


如果第三個參數(shù)immediate傳true院塞,則會立即執(zhí)行一次調(diào)用遮晚,后續(xù)的調(diào)用不會在執(zhí)行,可以自己在代碼中試一下

14 節(jié)流
多次調(diào)用方法拦止,按照一定的時間間隔執(zhí)行

這個方法的實現(xiàn)也是從Lodash庫中copy的

/**
 * 節(jié)流县遣,多次觸發(fā),間隔時間段執(zhí)行
 * @param {Function} func
 * @param {Int} wait
 * @param {Object} options
 */
export function throttle(func, wait=500, options) {
    //container.onmousemove = throttle(getUserAction, 1000);
    var timeout, context, args
    var previous = 0
    if (!options) options = {leading:false,trailing:true}

    var later = function() {
        previous = options.leading === false ? 0 : new Date().getTime()
        timeout = null
        func.apply(context, args)
        if (!timeout) context = args = null
    }

    var throttled = function() {
        var now = new Date().getTime()
        if (!previous && options.leading === false) previous = now
        var remaining = wait - (now - previous)
        context = this
        args = arguments
        if (remaining <= 0 || remaining > wait) {
            if (timeout) {
                clearTimeout(timeout)
                timeout = null
            }
            previous = now
            func.apply(context, args)
            if (!timeout) context = args = null
        } else if (!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaining)
        }
    }
    return throttled
}

第三個參數(shù)還有點復(fù)雜汹族,options

leading萧求,函數(shù)在每個等待時延的開始被調(diào)用,默認(rèn)值為false
trailing顶瞒,函數(shù)在每個等待時延的結(jié)束被調(diào)用夸政,默認(rèn)值是true
可以根據(jù)不同的值來設(shè)置不同的效果:

leading-false,trailing-true:默認(rèn)情況榴徐,即在延時結(jié)束后才會調(diào)用函數(shù)
leading-true守问,trailing-true:在延時開始時就調(diào)用,延時結(jié)束后也會調(diào)用
leading-true, trailing-false:只在延時開始時調(diào)用
例子:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
    </head>
    <body>
        <input id="input" />
        <script>
            function onInput() {
                console.log('1111')
            }
            const throttleOnInput = throttle(onInput)
            document
                .getElementById('input')
                .addEventListener('input', throttleOnInput) //在Input中輸入坑资,每隔500ms執(zhí)行一次代碼
        </script> 
    </body>
</html>
  1. cleanObject
    去除對象中value為空(null,undefined,'')的屬性,舉個栗子:
let res=cleanObject({
    name:'',
    pageSize:10,
    page:1
})
console.log("res", res) //輸入{page:1,pageSize:10}   name為空字符串耗帕,屬性刪掉

使用場景是:后端列表查詢接口,某個字段前端不傳袱贮,后端就不根據(jù)那個字段篩選仿便,例如name不傳的話,就只根據(jù)page和pageSize篩選攒巍,但是前端查詢參數(shù)的時候(vue或者react)中探越,往往會這樣定義

export default{
    data(){
        return {
            query:{
                name:'',
                pageSize:10,
                page:1
            }
        }
    }
}


const [query,setQuery]=useState({name:'',page:1,pageSize:10})

給后端發(fā)送數(shù)據(jù)的時候,要判斷某個屬性是不是空字符串窑业,然后給后端拼參數(shù)钦幔,這塊邏輯抽離出來就是cleanObject,代碼實現(xiàn)如下

export const isFalsy = (value) => (value === 0 ? false : !value);

export const isVoid = (value) =>
  value === undefined || value === null || value === "";

export const cleanObject = (object) => {
  // Object.assign({}, object)
  if (!object) {
    return {};
  }
  const result = { ...object };
  Object.keys(result).forEach((key) => {
    const value = result[key];
    if (isVoid(value)) {
      delete result[key];
    }
  });
  return result;
};


let res=cleanObject({
    name:'',
    pageSize:10,
    page:1
})
console.log("res", res) //輸入{page:1,pageSize:10}

作者:_紅領(lǐng)巾
https://juejin.cn/post/7000919400249294862
如有侵權(quán)聯(lián)系小編刪除常柄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鲤氢,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子西潘,更是在濱河造成了極大的恐慌卷玉,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喷市,死亡現(xiàn)場離奇詭異相种,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)品姓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門寝并,熙熙樓的掌柜王于貴愁眉苦臉地迎上來箫措,“玉大人,你說我怎么就攤上這事衬潦〗锫” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵镀岛,是天一觀的道長弦牡。 經(jīng)常有香客問我,道長漂羊,這世上最難降的妖魔是什么驾锰? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮走越,結(jié)果婚禮上椭豫,老公的妹妹穿的比我還像新娘。我一直安慰自己买喧,他們只是感情好捻悯,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布匆赃。 她就那樣靜靜地躺著淤毛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪算柳。 梳的紋絲不亂的頭發(fā)上低淡,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天,我揣著相機(jī)與錄音瞬项,去河邊找鬼蔗蹋。 笑死,一個胖子當(dāng)著我的面吹牛囱淋,可吹牛的內(nèi)容都是我干的猪杭。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼妥衣,長吁一口氣:“原來是場噩夢啊……” “哼皂吮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起税手,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤蜂筹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芦倒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艺挪,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年兵扬,在試婚紗的時候發(fā)現(xiàn)自己被綠了麻裳。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片口蝠。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖掂器,靈堂內(nèi)的尸體忽然破棺而出亚皂,到底是詐尸還是另有隱情,我是刑警寧澤国瓮,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布灭必,位于F島的核電站,受9級特大地震影響乃摹,放射性物質(zhì)發(fā)生泄漏禁漓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一孵睬、第九天 我趴在偏房一處隱蔽的房頂上張望播歼。 院中可真熱鬧,春花似錦掰读、人聲如沸秘狞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烁试。三九已至,卻和暖如春拢肆,著一層夾襖步出監(jiān)牢的瞬間减响,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工郭怪, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留支示,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓鄙才,卻偏偏與公主長得像颂鸿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子攒庵,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容