js技巧
对数组解构快速拿到最后一项值
实际上我们是可以对数组解构赋值拿到length属性的,通过这个特性也可以做更多的事情。
const arr = [1, 2, 3];
const { 0: first, length, [length - 1]: last } = arr;
first; // 1
last; // 3
length; // 3
比较两个时间大小
通过调用getTime获取时间戳比较就可以了
function compare(a, b){
return a.getTime() > b.getTime();
}
判断是空对象
1、最常见的思路,for...in...遍历属性,为真则为“非空数组”;否则为“空数组”
function judgeObj(Obj){
for(var attr in Obj){
return alert('非空对象')
}
return alert('空对象')
}
2.通过JSON自带的.stringify方法来判断:
if(Json.stringify(Obj) == '{}' ){
console.log('空对象');
}
3.ES6新增的方法Object.keys():
if(Object.keys(Obj).length > 0){
console.log('非空对象');
}
巧用match
str.match(regexp)
注意返回值
- 如果正则使用了g标识,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组
- 如果未使用g标志,则仅返回第一个完整匹配及其相关的捕获组(
Array)- 如果正则含有小括号分组,则也会把分组匹配的结果放到数组中
捕获组:
groups: 一个捕获组数组 或undefined(如果没有定义命名捕获组)。index: 匹配的结果的开始位置input: 搜索的字符串
包含捕获组
a=‘123'
a.match(/\d*/)
["1", index: 0, input: "1,2,3,4", groups: undefined]
不包含捕获组
a=‘123'
a.match(/\d/g)
["1", "2", "3"]
避免使用魔术字符串
- 魔术字符串是指在代码中多次出现,与代码形成强耦合的某一字符串或数值,不利于将来的修改和维护。在编写代码时应尽量消除魔术字符串,用变量代替
这样如果要修改这个字符串只用更改一个地方即可,方便快捷也不会导致程序出错
扁平数据结构转Trees
结构:
//pid 表示他的父级 id, 做关系映射
const arr = [
{ id: 3, name: '部门3', pid: 1 },
{ id: 1, name: '部门1', pid: 0 },
{ id: 4, name: '部门4', pid: 3 },
{ id: 2, name: '部门2', pid: 1 },
{ id: 5, name: '部门5', pid: 4 },
];
递归
//pid 表示他的父级 id, 做关系映射
const arr = [
{ id: 3, name: "部门3", pid: 1 },
{ id: 1, name: "部门1", pid: 0 },
{ id: 4, name: "部门4", pid: 3 },
{ id: 2, name: "部门2", pid: 1 },
{ id: 5, name: "部门5", pid: 4 },
];
const genTree = (data, pid) => {
const result = [];
for (const item of data) {
if (item.pid === pid) {
result.push({ ...item, childrem: genTree(data, item.id) });
}
}
return result;
};
const tree = genTree(arr, 0);
console.dir(tree, { depth: 100 });
非递归实现,reduce
function arrayToTree(arr) {
const map = {}; //键值对存储,使用对象的引用
return arr
.sort((a, b) => a.id - b.id) //考虑乱序的情况,对id进行升序排序
.reduce((acc, cur) => {
const { id, pid } = cur;
if (!map[id]) {
map[id] = Object.assign(cur, { children: [] });
}
if (!cur.pid) {
acc.push(cur);
} else {
map[pid].children.push(map[id]);
}
return acc;
}, []);
}
console.time();
const tree = arrayToTree(arr);
console.timeEnd();
console.log(tree);
处理文件下载(带请求头)
文件下载通常使用a标签进行处理,本次介绍的是通过blob来实现流文件下载,原因是后台网关校验通过请求头拿token
- a标签指定 download 属性的值,它将是下载文件的新文件名
import { message } from 'antd'
function createObjectURL (object) {
return window.URL ? window.URL.createObjectURL(object) : window.webkitURL.createObjectURL(object)
}
async function fileDownload ({ token,method='get', url,data,title }) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest()
xhr.open(method, url)
xhr.setRequestHeader('access-token', token)
xhr.responseType = 'blob'
xhr.setRequestHeader('Content-Type', 'application/json')
xhr.onload = function (e) {
const dis = xhr.getResponseHeader('Content-Disposition')
if (this.status == 200) {
var blob = this.response
var filename = `${title}.xls`
console.log(this.response)
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename)
} else {
var a = document.createElement('a')
var URL = createObjectURL(blob)
console.log('URL', url)
a.href = URL
//文件名解码
a.download = dist?decodeURIComponent(dis.split('attachment;filename=')[1]):title
document.body.appendChild(a)
a.click()
window.URL.revokeObjectURL(URL)
}
resolve(true)
}else{
reject(false)
}
}
xhr.onerror = err => {
message.error('下载失败,请重新尝试')
reject(err)
}
xhr.send(JSON.stringify(data))
})
}
export default fileDownload
try/catch方法封装
type PromiseOption = {
successFn?: (result: any) => void;
errorFn?: (error: any) => void;
finallyFn?: () => void;
};
export async function usePromise(promise, option?: PromiseOption) {
try {
const result = await promise;
option?.successFn?.(result);
return [null, result];
} catch (error) {
option?.errorFn?.(error);
return [error, null];
} finally {
option?.finallyFn?.();
}
}
// 使用
// const [error,result] = await usePromise(yourAsync())
js下载url视频
import { forEach } from 'lodash-es';
import { useLoading } from './useLoading';
// 视频相关方法
export function useMaterial() {
const { loading: downloadLoading, setLoading: setDownloadLoading } = useLoading();
const downloadFile = async ({ url, name, isLoading = false }) => {
try {
isLoading && setDownloadLoading(true);
const response = await fetch(url);
const blob = await response.blob();
const blobUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = blobUrl;
link.download = name;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(blobUrl);
} catch (error) {
console.error('下载失败:', error);
} finally {
isLoading && setDownloadLoading(false);
}
};
const batchDownloadFile = (data) => {
forEach(data, (item) => {
downloadFile({ url: item.url, name: item.name, isLoading: false });
});
};
return {
downloadFile,
downloadLoading,
batchDownloadFile,
};
}
二进制转化图片url
- URL.createObjectURL(object)
- 用于创建 URL 的
File对象、Blob对象
- 用于创建 URL 的