2021-03-07 分類: 網(wǎng)站建設(shè)
這篇文章主要記錄一下平時(shí)自己實(shí)踐得到的, 博客中學(xué)習(xí)的以及在一些項(xiàng)目源碼中看到的 javascript 技巧。有些東西可以說(shuō)是奇淫技巧,有些可能是 ES6+ 中一些比較具有實(shí)用性的新語(yǔ)法。
&& 和 || 的妙用
有時(shí)候我們需要在某個(gè)函數(shù)或變量為 true 時(shí)執(zhí)行另外一個(gè)函數(shù)。例如:
const task1 = () => { console.log('執(zhí)行 task1'); return Math.random() >= 0.5; } const task2 = () => console.log('task1 執(zhí)行成功后執(zhí)行 task2'); if (task1()) task2();
上面的 if 語(yǔ)句可以使用 && 直接簡(jiǎn)寫(xiě)為:
task1() && task2();
如果還要在 task1 失敗(也就是task1返回false)后執(zhí)行 task3, 可以使用:
const task3 = () => console.log('task1 執(zhí)行失敗后執(zhí)行 task3'); task1() && task2() || task3();
本質(zhì)上還是利用了 && 和 || 的短路特性。
其實(shí)這里使用條件運(yùn)算符也是可以的:
task1() ? task2() : task3();
下面展示的我最近的一個(gè)使用 react hooks 開(kāi)發(fā)的項(xiàng)目中的一個(gè)代碼片段,這里利用了 render props:
const ProfileItem = (props) => { const { name, value, render } = props; return (
函數(shù)默認(rèn)值
ES5 版本
使用短路或操作符來(lái)設(shè)置函數(shù)默認(rèn)值的方式其實(shí)很常見(jiàn)。但是有一些坑,下面展示的代碼中當(dāng)默認(rèn)值參數(shù)為一個(gè)數(shù)字時(shí),傳參為 0 還是會(huì)使用默認(rèn)值,必須對(duì) y 為 0 的時(shí)候單獨(dú)進(jìn)行判斷。
const pow = (x, y) => { y = y || 2; let result = 1; for (let i = 0, max = y; i < max; i++) { result *= x; } return result; } console.log(pow(2)); // => 4 console.log(pow(2, 3)); // => 8 // 當(dāng) y 傳值為 0 時(shí), y 取值 2 console.log(pow(2, 0)); // => 4
ES6 版本
ES6 在語(yǔ)法層面提供的默認(rèn)值語(yǔ)法就靠譜的多了
const pow = (x, y=2) => { let result = 1; for (let i = 0, max = y; i < max; i++) { result *= x; } return result; } console.log(pow(2)); // => 4 console.log(pow(2, 3)) // => 8 console.log(pow(2, 0)); // => 1
類數(shù)組轉(zhuǎn)數(shù)組
類數(shù)組指的是像 arguments ,jquery 對(duì)象一樣可以使用下標(biāo)訪問(wèn)還有 length 屬性的和數(shù)組很像但并不是數(shù)組的一類對(duì)象。
類數(shù)組沒(méi)有 slice, map 等集合函數(shù),這也是為什么我們有時(shí)候需要將類數(shù)組轉(zhuǎn)換成數(shù)組的原因。
function func() { for (let i = 0, max = arguments.length; i < max; i++) { console.log(arguments[i]); } console.log(Array.isArray(arguments)); // => false // 類數(shù)組沒(méi)有 slice, forEach, map 等集合函數(shù) console.log(arguments.slice === undefined); // => true } func('Google', 'facebook', 'Microsoft'); // => // Google // facebook // Microsoft
ES5 中的轉(zhuǎn)換方法
將 Array 原型中的 slice 方法綁定到 arguments 對(duì)象上調(diào)用,并且不傳參數(shù)目的為了讓其返回所有的元素。
function func() { const array = Array.prototype.slice.call(arguments); console.log(array.slice(0, 1)); } func('Google', 'facebook', 'Microsoft'); // => [ 'Google' ]
ES6 中的轉(zhuǎn)換方法
ES6 將類數(shù)組轉(zhuǎn)換成數(shù)組的方法多一些。
使用擴(kuò)展運(yùn)算符
function func() { console.log([...arguments]) } func('Google', 'facebook', 'Microsoft'); // [ 'Google', 'facebook', 'Microsoft' ]
使用 Array.from
function func() { console.log(Array.from(arguments)) } func('Google', 'facebook', 'Microsoft'); // [ 'Google', 'facebook', 'Microsoft' ]
構(gòu)造一個(gè)連續(xù)整數(shù)的數(shù)組
這里就直接給出我覺(jué)得最好的方法了
// 輸出 2 開(kāi)始連續(xù)的8個(gè)整數(shù) const array = Array.from({ length: 8}).map((ele, index) => index + 2); console.log(array); // => [ 2, 3, 4, 5, 6, 7, 8, 9 ]? // 評(píng)論區(qū)指出有更簡(jiǎn)潔的版本, Array.from 自帶的映射函數(shù) const array = Array.from({ length: 8}, (ele, index) => index + 2); console.log(array); // => [ 2, 3, 4, 5, 6, 7, 8, 9 ]? // 還有一個(gè)網(wǎng)友指出可以利用 Array.prototype.keys 來(lái)構(gòu)造 const array = [...Array(8).keys()].map((ele, index) => index + 2)
函數(shù)參數(shù)使用解構(gòu)賦值
函數(shù)參數(shù)比較多的時(shí)候我們往往會(huì)讓參數(shù)直接接受一個(gè)配置對(duì)象。但是使用對(duì)象參數(shù)我們無(wú)法設(shè)置默認(rèn)值,在函數(shù)體中使用對(duì)象參數(shù)時(shí)還需要使用通過(guò)對(duì)象參數(shù)來(lái)訪問(wèn),當(dāng)訪問(wèn)次數(shù)比較多或者嵌套比較深就會(huì)覺(jué)得不方便。在函數(shù)參數(shù)中使用解構(gòu)賦值就解決了上面的問(wèn)題。
// 必須給對(duì)象參數(shù)設(shè)置默認(rèn)值, 不然傳參數(shù)時(shí)因?yàn)闆](méi)有解構(gòu)對(duì)象會(huì)報(bào)錯(cuò) const getUsers = ({ offset=0, limit=1, orderBy="salary" }={}) => { // 根據(jù)條件查詢數(shù)據(jù)庫(kù)返回用戶數(shù)據(jù) console.log({ offset, limit, orderBy }); } getUsers({ offset: 10, limit: 20,orderBy: 'age' }); // => { offset: 10, limit: 20, orderBy: 'age' } getUsers();// => { offset: 0, limit: 1, orderBy: 'salary' }
使用 !! 將其它類型轉(zhuǎn)換成 bool 型
console.log(!!{}); // true console.log(!!0); // false console.log(!![]); // true console.log(!!undefined); // false const httpGet = (url, retry) => { if (!!retry) { // 超時(shí)重發(fā) } }
JSON.stringify
深度克隆
使用先序列化再反序列化這種方式來(lái)深度克隆對(duì)象在一般情況下很方便,缺點(diǎn)就是無(wú)法克隆函數(shù)以及繼承的屬性。
如果還要克隆函數(shù)屬性,推薦使用 lodash 的 cloneDeep。
const me = { name: 'lyreal666', age: 23, speak() { console.log(`Hello, I'm ly!`); } } const clonEDMe = JSON.parse(JSON.stringify(me)); console.log(clonEDMe); // => { name: 'lyreal666', age: 23 } console.log(clonEDMe.speak === undefined); // => true
使用第二個(gè)和第三參數(shù)
JSON.stringify 的第二個(gè)參數(shù)是用來(lái)對(duì)屬性值進(jìn)行處理的,第三個(gè)參數(shù)則是用來(lái)指定輸出的 json 字符串的縮進(jìn)長(zhǎng)度,可以傳數(shù)字也可以傳字符串。
const me = { name: 'lyreal666', age: 23, speak() { console.log(`Hello, I'm ly!`); } } const jsonStr = JSON.stringify(me, (key, value) => key === 'name' ? '老余' : value, 2); console.log(jsonStr); /* => { "name": "老余", "age": 23 } */
優(yōu)雅的遍歷對(duì)像
使用解構(gòu)賦值和 Object.entries。
const me = { name: 'lyreal666', age: 23, speak() { console.log(`Hello, I'm ly!`); } } for (const [key, value] of Object.entries(me)) { console.log(`${key}: ${value}`); } /* => name: lyreal666 age: 23 speak: speak() { console.log(`Hello, I'm ly!`); } */
清空數(shù)組的最快方法
評(píng)論區(qū)有人說(shuō)這種直接修改 length 的做法是有問(wèn)題的, 我之前也看過(guò)關(guān)于清空數(shù)組的方法的討論, 但是我覺(jué)得一般情況下這樣用是沒(méi)什么問(wèn)題的, 既簡(jiǎn)單, 又不用重新分配內(nèi)存給新數(shù)組。
const array = [1, 2, 3, 4]; array.length = 0; console.log(array); // => [] // 網(wǎng)友指出可以更好的方式是直接賦值空數(shù)組 let array = [1, 2, 3, 4]; array = []; 復(fù)制代碼 判斷一個(gè)整數(shù)是否是 -1 // ~ 操作符的運(yùn)算規(guī)律可以簡(jiǎn)單記作將加一的結(jié)果取反 console.log(~1); // => -2 console.log(~0); // => -1 console.log(~(-3)); // => 2 console.log(~(-1)); // => 0 const number = -2; // 判斷一個(gè)數(shù)是否為 -1 if (!~number) { // 當(dāng) number 是 -1 的操作... }
立即執(zhí)行函數(shù)
立即執(zhí)行函數(shù)可以讓我們的代碼中的變量不污染外部變量,常見(jiàn)的使用方式是像下面這樣的。
// 使用括號(hào)將函數(shù)括起來(lái)調(diào)用 (function(window, $) { // 內(nèi)部代碼 }) (window, jQuery) 復(fù)制代碼 更優(yōu)雅的方式是下面這種,事實(shí)上很多其它的算術(shù)運(yùn)算符比如 +, -, *, ~ 等也是可以的。 ! function(window, $) { // 內(nèi)部代碼 } (window, jQuery) // 還可以使用 +, -, * 等 + function(window, $) { // 內(nèi)部代碼 } (window, jQuery) // 更神奇的是還可以用 new, typeof 等操作符 new function(window, $) { // 內(nèi)部代碼 } (window, jQuery);
使用 set 來(lái)對(duì)數(shù)組去重復(fù)
console.log([...new Set([1, 3, 1, 2, 2, 1])]); // => [ 1, 3, 2 ]
使用 reduce 連乘或連加
const array = [ 1, 2, 3, 4]; // 連加 console.log(array.reduce((p, c) => p + c)); // => 10 // 連乘 console.log(array.reduce((p, c) => p * c)); // => 24 復(fù)制代碼 取整 Math 中的一堆取整函數(shù)這里就不說(shuō)了,主要是提一些比較巧妙地取整方式。 console.log(~~3.14); // => 3 console.log(~~(-2.5)); // => -2 console.log(6.18 | 0); // => 6 console.log(-3.6 | 0); // => -3 console.log(9.9 >> 0); // => 9 console.log(-2.1 >> 0); // => -2 // superagent 是一個(gè)很實(shí)用的發(fā)送 http 請(qǐng)求的 node 模塊,它對(duì)返回碼的處理就用到了 | var type = status / 100 | 0; // status / class res.status = status; res.statusType = type; // basics res.info = 1 == type; res.ok = 2 == type; res.clientError = 4 == type; res.serverError = 5 == type; res.error = 4 == type || 5 == type;
使用 + 將其它類型轉(zhuǎn)換成 number 類型
console.log(+'3.14'); // => 3.14 console.log(typeof +'3.14') // => number const sleep = (milliseconds) => { return new Promise((resolve, reject) => { setTimeout(() => resolve(), milliseconds); }); } // 當(dāng)然這里可以考慮使用 console.time 來(lái)測(cè)試 ! async function main() { const start = +new Date(); await sleep(3000); const end = +new Date(); console.log(`執(zhí)行了${end - start}`); // 執(zhí)行了 3002 }();
使用科學(xué)計(jì)數(shù)法表示大數(shù)字
const str1 = 'hello'; const str2 = ' world' console.time('測(cè)試 + 拼接字符串'); for (let i = 0; i < 200000000; i++) { const joinedStr = str1 + str2; } console.timeEnd('測(cè)試 + 拼接字符串'); console.time('測(cè)試模板字符串拼接字符串'); // 使用科學(xué)計(jì)數(shù)法比打 8 個(gè) 0 方便不少 for (let i = 0; i < 2E8; i++) { const joinedStr =`${str1}${str2}`; } console.timeEnd('測(cè)試模板字符串拼接字符串') /* => 測(cè)試 + 拼接字符串: 3238.037ms 測(cè)試模板字符串拼接字符串: 3680.225ms */
交換變量值
直接利用解構(gòu)賦值
let a = 666; let b = 999; [a, b] = [b, a]; console.log({ a, b }); // => { a: 999, b: 666 }
獲取隨機(jī)字符串
截取下標(biāo) 2 開(kāi)始后的字符串是因?yàn)椴恍枰?Math.random() 返回的小數(shù)構(gòu)成的字符串的 0. 這兩個(gè)字符。使用 36 進(jìn)制可以制造字符種類更多些的隨機(jī)字符串
console.log(Math.random().toString(16).substring(2)); // 13位 => 45d9d0bb10b31 console.log(Math.random().toString(36).substring(2)); // 11位 => zwcx1yewjvj
扁平化數(shù)組
ES 2019 新增了 Array.prototype.flat,目前 chrome 最新正式版 73.0.3683.103 已經(jīng)支持了, node 最新的 LTS 10.15.3 還不支持, node 最新開(kāi)發(fā)版 11.13.0 是支持的。這里貼一個(gè)在掘金一個(gè)兄弟面經(jīng)里面看到的比較 hack 的方法,這里要注意根據(jù)情況做類型轉(zhuǎn)換。
const array = [1, [2, [3, 4], 5], 6, 7]; console.log(array.toString().split(',').map(ele => Number.parseInt(ele))); // => [ 1, 2, 3, 4, 5, 6, 7 ]
以下是總結(jié)出來(lái)最全前端框架視頻,包含: javascript/vue/react/angualrde/express/koa/webpack 等學(xué)習(xí)資料。
文章標(biāo)題:JavaScript編程中常用到的一些小技巧
本文地址:http://jinyejixie.com/news/104619.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、動(dòng)態(tài)網(wǎng)站、品牌網(wǎng)站建設(shè)、營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容