本文整理了日常开发中高频使用的 JS 技巧,涵盖数据处理、性能优化、语法简化等场景,帮助你写出更简洁、高效的代码。
一、变量与类型处理
1. 变量解构赋值
快速提取对象/数组中的值,简化变量声明。
js
// 数组解构
const [a, b, c = '默认值'] = [1, 2];
console.log(a, b, c); // 1 2 默认值
// 对象解构
const user = { name: '张三', age: 20 };
const { name, age: userAge } = user; // 重命名属性
console.log(name, userAge); // 张三 20
2. 类型判断
精准判断数据类型(避免 typeof 对 null/数组等的误判):
js
const getType = (val) => Object.prototype.toString.call(val).slice(8, -1).toLowerCase();
console.log(getType('')); // string
console.log(getType([])); // array
console.log(getType(null)); // null
console.log(getType(new Date())); // date
3. 空值合并/可选链
处理空值场景,避免 Cannot read property 'xxx' of undefined 错误:
js
// 可选链 (?.):属性不存在时返回 undefined
const obj = { a: { b: 1 } };
console.log(obj?.a?.b); // 1
console.log(obj?.c?.d); // undefined
// 空值合并 (??):仅当值为 null/undefined 时使用默认值(区别于 ||)
const num = 0;
console.log(num || 10); // 10(|| 会把 0/'' 等假值判定为 false)
console.log(num ?? 10); // 0(仅 null/undefined 触发默认值)
二、数组操作
1. 数组去重
简洁高效的去重方式(ES6+):
js
// 方法1:Set(适用于基本类型)
const arr = [1, 2, 2, 3, 3, 3];
const uniqueArr = [...new Set(arr)];
console.log(uniqueArr); // [1,2,3]
// 方法2:filter + indexOf(支持复杂场景)
const uniqueArr2 = arr.filter((item, index) => arr.indexOf(item) === index);
2. 数组扁平化
多层数组转为一维数组:
js
// 方法1:flat(指定深度,Infinity 表示无限深度)
const deepArr = [1, [2, [3, [4]]]];
console.log(deepArr.flat(2)); // [1,2,3,[4]]
console.log(deepArr.flat(Infinity)); // [1,2,3,4]
// 方法2:递归 + 扩展运算符(兼容低版本)
const flatten = (arr) => arr.reduce((acc, val) =>
acc.concat(Array.isArray(val) ? flatten(val) : val), []
);
console.log(flatten(deepArr)); // [1,2,3,4]
3. 数组快速求和/最大值/最小值
js
const nums = [1, 2, 3, 4];
// 求和
const sum = nums.reduce((acc, cur) => acc + cur, 0); // 10
// 最大值/最小值
const max = Math.max(...nums); // 4
const min = Math.min(...nums); // 1
三、对象操作
1. 合并对象
js
const obj1 = { a: 1 };
const obj2 = { b: 2 };
// 方法1:扩展运算符(浅拷贝)
const mergeObj = { ...obj1, ...obj2 }; // {a:1, b:2}
// 方法2:Object.assign(浅拷贝)
const mergeObj2 = Object.assign({}, obj1, obj2);
// 深合并(需手动实现或用 lodash 的 _.merge)
2. 遍历对象
js
const obj = { a: 1, b: 2 };
// 遍历键值对
Object.entries(obj).forEach(([key, value]) => {
console.log(key, value); // a 1 | b 2
});
// 仅遍历键
Object.keys(obj).forEach(key => console.log(key)); // a | b
// 仅遍历值
Object.values(obj).forEach(value => console.log(value)); // 1 | 2
3. 动态对象属性名
js
const key = 'name';
const obj = {
[key]: '张三', // 动态属性名
[`${key}Age`]: 20 // 拼接属性名
};
console.log(obj); // {name: '张三', nameAge: 20}
四、性能与语法简化
1. 短路求值
js
// 条件执行(替代 if)
const flag = true;
flag && console.log('执行'); // 执行
flag || console.log('不执行'); // 无输出
// 赋值默认值
const val = undefined;
const res = val || '默认值'; // 默认值
2. 快速交换变量
js
let x = 1, y = 2;
[x, y] = [y, x]; // 交换值
console.log(x, y); // 2 1
3. 函数默认参数
js
function fn(a = 1, b = 2) {
return a + b;
}
console.log(fn()); // 3
console.log(fn(3)); // 5
4. 箭头函数简化
js
// 单行返回(省略 {} 和 return)
const add = (a, b) => a + b;
// 返回对象(需加 ())
const createObj = (name) => ({ name, age: 20 });
5. 防抖与节流(高频场景)
js
// 防抖(触发后延迟执行,多次触发重置计时)
function debounce(fn, delay = 500) {
let timer = null;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => fn.apply(this, args), delay);
};
}
// 节流(固定频率执行)
function throttle(fn, interval = 500) {
let flag = true;
return (...args) => {
if (!flag) return;
flag = false;
setTimeout(() => {
fn.apply(this, args);
flag = true;
}, interval);
};
}
五、其他实用技巧
1. 生成随机数/随机字符串
js
// 生成 [min, max] 范围内的随机整数
const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
// 生成随机字符串(如验证码)
const randomStr = (len = 6) => {
const chars = '0123456789abcdefghijklmnopqrstuvwxyz';
return Array(len).fill('').map(() => chars[Math.floor(Math.random() * chars.length)]).join('');
};
2. 时间戳转日期格式
js
const formatDate = (timestamp) => {
const date = new Date(timestamp);
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
};
console.log(formatDate(Date.now())); // 2026-03-12(示例)
3. 数组/对象深拷贝
js
// 简易深拷贝(仅支持 JSON 可序列化类型)
const deepClone = (obj) => JSON.parse(JSON.stringify(obj));
// 完整深拷贝(需处理函数/正则等特殊类型)
function deepClone2(obj) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
const cloneObj = Array.isArray(obj) ? [] : {};
for (let key in obj) {
cloneObj[key] = deepClone2(obj[key]);
}
return cloneObj;
}
总结
- 语法简化:解构赋值、可选链、空值合并、箭头函数等能大幅简化代码,提升可读性;
- 数据处理:数组去重/扁平化、对象合并/遍历是高频场景,优先使用 ES6+ 原生方法;
- 性能优化:防抖/节流可解决高频触发(如滚动、输入)的性能问题,深拷贝需注意数据类型兼容性。
这些技巧覆盖了 80% 以上的日常开发场景,核心是用更简洁、符合规范的方式实现需求,同时兼顾可读性和性能。