记录在工作中可能会常用到的语法技巧
Tips - (暂时不考虑兼容性)
last update : 2022年11月25日21:57:41
-----------main----------------
一、用at(-1) 替代arr.length-1
let arr = [1, 2, 3, 4, 5];
let lastLength = arr[arr.length - 1];
// 简化
lastLength = arr.at(-1);
# 二、用?.代替&&运算符
let obj = { name: '1' };
let name = obj && obj.name;
// 简化
name = obj?.name;
三、使用arr.flat扁平化数组
let arr = [1,2,3,4,[5,6,7,8,[9,10]]]
//简化
let flatArr = arr.flat(Infinity); //传入Infinity可扁平二维以上数组
# 四、promise async await
async fun(){
let result = await promiseApi();
}
# 五、Object.keys || Object.values
let obj = {
name: '1',
arr: [1, 2, 3, 4]
}
let temp = [];
//需要拿到obj的values || keys
for (let k in obj) {
temp.push(k) //keys //temp.push(obj[k]) //values
}
//简化
temp = Object.keys(obj);
temp = Object.values(obj);
六、使用...语法糖 合并 || 解构
let obj = { name: '1', TempArr: ['a', 'b', 'c', 'd'] }
let obj1 = { age: '18' }
//合并对象
let assignObj = { ...obj, ...obj1 }
let arr = [1, 2, 3, 4]
let arr1 = [5, 6, 7, 8]
//合并数组
let assignArr = [...arr, ...arr1];
//解构赋值
let { TempArr } = obj;
let [a, b, c, d] = TempArr;
# 七、数组去重
let arr = [1, 2, 3, 4, 5, 4, 5, '4', '5'];
//简化
let unique = Array.from(new Set(arr))
console.log(unique, 'unique 不会去除字符串4、5')
八、数组计算
let arr = [1, 2, 3, 4, 5, 6, -100, 521];
let max = Math.max(...arr);
let min = Math.min(...arr);
let count = arr.reduce((a,b) => a+b); //442
console.log(max) //521
console.log(min) //-100
九、replaceAll 全部替换
let str = "Hi!,这是ES6~ES12的新特性,目前为ES12"
console.log(str.replace("ES", "SY")); // Hi!,这是SY6~ES12的新特性,目前为ES12
console.log(str.replaceAll("ES", "Sy")); // Hi!,这是Sy6~Sy12的新特性,目前为Sy12
十、对象映射改造干掉IF SWITCH
function fun(type) {
// 假如有这样一段代码
if (type === "success") {
return "green";
}
if (type === "warning") {
return "yellow";
}
if (type === "error") {
return "red";
}
// switch改造
switch (type) {
case "success":
return "green";
case "warning":
return "yellow";
case "error":
return "red";
}
// 对象映射改造
const typeMap = {
success: "green",
warning: "yellow",
error: "red",
};
//如果需要默认值可以用??运算符 比如 typeMap['ok'] 没有的话 会返回??后的内容
return typeMap[type]??'默认值';
}
十一、多维数组扁平化(递归方式)
const multipleArr = [[1, 2, 3],[4, 5, 6],[7, 8, 9],[10, [11, [12, [13]]]]]
function flatArr(data, r = []) {
data.map(x => {
if (Array.isArray(x) && x.length) {
flatArr(x, r);
} else {
r.push(x);
}
})
return r;
}
let fArr = flatArr(multipleArr)
十二、数组转Tree(递归)
function toTree(data, nodeId = 0, r = []) {
// 判断arr是否是数组
if (!Array.isArray(data)) return []
data.map(x => (x.pid === nodeId) && r.push({ ...x, children: toTree(data, x.id) }));
return r;
}
let r = toTree(arr);
十三、数组转Tree(map对象 + 循环 性能对比递归更好)
/* 转map再进行数据查找 可控制对比的键名是 key 还是 id pid 传字符串 比如有的数据是parentId */
arrayToTree(arr, keyPath = 'key', pid, r = [], map = {}) {
arr.map(item => {
item.children = [];
map[item[keyPath]] = item
})
arr.map(x => map[x[pid]] ? map[x[pid]].children.push(x) : r.push(x))
return r
},
//demo 因为这里键是id 所以 我选择传入id 默认是key
let temp = [
{
id:'1000',
name:'哈哈'
},
{
id:'1001',
name:'呵呵',
pid:'1000'
},
{
id:'1002',
name:'嘻嘻',
pid:'1001'
},
{
id:'1003',
name:'哈哈哈呢'
},
]
console.log(this.arrayToTree(temp,'id'))
十四、Tree转数组
//tree转数组
function toArray(tree) {
let nTree = JSON.parse(JSON.stringify(tree)); //深拷贝
if (!Array.isArray(nTree) || !nTree.length) throw new Error("请传入数组")
for (let i = 0; i < nTree.length; i++) {
if (nTree[i].children) {
// 每次children有值,就把值合并到原始数据tree上去
//增加tree长度,for循环的长度也会增加 依次处理...
nTree = nTree.concat(nTree[i].children)
delete nTree[i].children
}
}
return nTree
}
let newArr = toArray(r);
十五、更爽的使用async await
# 我们在实际开发中经常会遇到后端返回接口是 res.data 这种形式,可我们只希望得到data
# 普通写法
this.getDicts('ispgb_clue_state').then(res=>{
this.xxx = res.data;
})
# 一般写法
let {data} = await this.getDicts('ispgb_clue_state')
this.xxx = data;
# 但是像上面这样写解构的话,如果接口返回错误,就会导致代码出错.
# 更好的写法
this.xxx = (await this.getDicts('ispgb_clue_state'))?.data || []
# 如果接口返回错误则会直接返回空数组 ?.data也可以.任意的你想要的对象属性
```
十六、判断对象或其原型上是否拥有某个属性
let obj = {
a: 1,
}
// 原型上拥有这个方法
console.log(obj.toString(), 'toString')
//只判断对象自身属性
console.log(obj.hasOwnProperty('toString'), 'hasOwnProperty'); //false
function searchObjHasAttr(obj, key) {
return key in obj
}
//也可以找到原型上的方法或属性
console.log(searchObjHasAttr(obj, 'toString'), 'key in obj ') //true
十七、从URL上获取参数并转换为对象格式
const getParameters = URL => JSON.parse(`{"${decodeURI(URL.split("?")[1]).replace(/"/g, '\"').replace(/&/g, '","').replace(/=/g, '":"')}"}`
)
getParameters("https://www.google.com.hk/search?q=js+md&newwindow=1");
// {q: 'js+md', newwindow: '1'}
十八、遍历对象及其属性获取某个需要的属性
/* 查找一个对象及其子属性中是否有某个属性值 */
export function findObjectAttribute(obj,key,result=[]){
for(let k in obj){
if(k===key){
if(obj[k]!==null&&obj[k]!==undefined){
result.push(obj[k])
}
}else{
//判断属性是否是对象
if(Object.prototype.toString.call(obj[k]) === '[object Object]'){
findObjectAttribute(obj[k],key,result)
}
//如果是数组
if(Array.isArray(obj[k])){
obj[k].map(item=>{
findObjectAttribute(item,key,result)
})
}
}
}
return result
}
//使用
let find_supervisionDeptOpinion = findObjectAttribute(processProgress,'supervisionDeptOpinion')
if(params?.supervisionDeptOpinion){
//返回的结果中只要有一条相等 即 返回
supervisionDeptOpinion = find_supervisionDeptOpinion.some(x=>{
return x===params.supervisionDeptOpinion
})
}
if(params.specialComments===true || params.specialComments===false){
//返回结果和查询结果匹配成功则为真
specialComments = params.specialComments===findObjectAttribute(processProgress,'opinions')?.length>0;
}
十九、下载文件
export default {
download(file) {
let url = file.fileUrl;
let name = file.documentName;
fetch(url).then(res => res.blob()).then((blob) => {
const link = document.createElement('a');
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.download = name
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
})
}
}
二十、数组对象去重+分组
//去重 + 分组 默认根据label去重
filterAndGroup(array, fun,deep='label') {
let obj = {}
let groups = {};
let newArr = array.reduce((prev, cur) => {
!obj[cur.deep] ? obj[cur.deep] = prev.push(cur) : '';
return prev
}, []);
newArr.forEach(v => {
let group = JSON.stringify(fun(v));
groups[group] = groups[group] || [];
groups[group].push(v);
});
return Object.keys(groups).map(group => {
return groups[group];
});
},