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