一、模板字符串:告别繁琐的字符串拼接
传统字符串拼接使用+运算符,在处理动态内容时容易出错且代码冗长。模板字符串通过反引号(`)包裹内容,支持${expression}`语法直接嵌入变量和表达式,极大提升代码可读性。
典型场景:动态生成HTML片段或复杂提示信息
// 传统方式const name = 'Alice';const age = 25;const message = 'Name: ' + name + ', Age: ' + age;// 模板字符串const message = `Name: ${name}, Age: ${age}`;
进阶用法:支持多行字符串和嵌套模板
const multiLine = `<div><h1>${name}</h1><p>Age: ${age}</p></div>`;
二、精确类型检测:Number.isInteger()
判断变量是否为整数时,传统方法存在精度问题。Number.isInteger()提供标准化的检测方式,避免隐式类型转换带来的意外结果。
对比示例:
// 传统方式的问题function isInt(value) {return typeof value === 'number' && value % 1 === 0;}isInt(3.0); // true(可能符合预期)isInt('3'); // false(但其他场景可能出错)// 标准方法Number.isInteger(3.0); // trueNumber.isInteger('3'); // falseNumber.isInteger(NaN); // false
三、表单值类型转换:valueAsNumber属性
处理表单输入时,event.target.value始终返回字符串类型,即使输入框限制为数字类型。使用valueAsNumber可直接获取数值类型,简化类型转换逻辑。
实际应用:
// 传统方式的问题const input = document.querySelector('#quantity');input.addEventListener('change', (e) => {const value = parseInt(e.target.value); // 需处理NaN情况if (isNaN(value)) { /* 错误处理 */ }});// 优化方案input.addEventListener('change', (e) => {const value = e.target.valueAsNumber; // 直接获取数值if (isNaN(value)) { /* 错误处理 */ }});
注意事项:当输入无效时(如空字符串),valueAsNumber返回NaN,需配合isNaN()进行检测。
四、逻辑短路:&&运算符的函数调用优化
通过&&运算符实现条件判断与函数调用的简洁写法,减少if语句的冗余代码。
典型模式:
// 传统方式if (isLoggedIn) {showDashboard();}// 优化写法isLoggedIn && showDashboard();
适用场景:
- 条件渲染(如React中的
&&逻辑) - 调试日志输出
- 权限控制下的功能调用
五、默认值设置:||运算符的陷阱与替代方案
使用||设置默认值时,需注意0、false、''等假值会被错误覆盖的问题。推荐使用??(空值合并运算符)或显式判断。
问题复现:
function setAge(age) {return age || 35; // 当age=0时返回35,不符合预期}
解决方案:
// 使用??运算符(ES2020)function setAge(age) {return age ?? 35; // 仅当age为null/undefined时使用默认值}// 传统显式判断function setAge(age) {if (age === undefined || age === null) {return 35;}return age;}
六、可选链操作符:?.简化深层属性访问
访问嵌套对象属性时,传统方式需逐层判断存在性。可选链操作符可简化代码并避免Cannot read property 'x' of undefined错误。
对比示例:
const user = { profile: { address: { city: 'Beijing' } } };// 传统方式const city = user && user.profile && user.profile.address && user.profile.address.city;// 可选链const city = user?.profile?.address?.city;
七、空值合并运算符:??的进阶应用
与||不同,??仅在左侧为null或undefined时返回右侧值,避免假值被意外覆盖。
使用场景:
const pagination = {limit: 0, // 用户可能显式设置为0page: null // 未设置的默认值};const effectiveLimit = pagination.limit ?? 10; // 0(保留用户设置)const effectivePage = pagination.page ?? 1; // 1(使用默认值)
八、数组解构:快速提取元素
通过解构赋值简化数组元素的提取,提升代码可读性。
典型用法:
const colors = ['red', 'green', 'blue'];// 传统方式const first = colors[0];const second = colors[1];// 解构赋值const [first, second] = colors;
剩余元素收集:
const [first, ...rest] = colors; // first='red', rest=['green','blue']
九、对象解构:属性提取与别名设置
对象解构支持直接提取属性、设置别名和默认值。
基础用法:
const user = { name: 'Bob', age: 30 };// 提取属性const { name, age } = user;// 设置别名const { name: userName, age: userAge } = user;// 默认值const { name, role = 'guest' } = user; // role='guest'
十、动态属性名:计算属性名
使用方括号[]定义动态属性名,适用于需要根据变量设置对象属性的场景。
示例:
const propName = 'email';const user = {[propName]: 'bob@example.com', // 等价于 email: 'bob@example.com'['first' + 'Name']: 'Bob' // 计算属性名};
十一、展开运算符:对象合并与复制
通过...运算符实现对象的浅拷贝和合并,替代Object.assign()。
合并对象:
const defaults = { theme: 'light', language: 'en' };const settings = { ...defaults, language: 'zh' }; // {theme:'light', language:'zh'}
浅拷贝限制:
const original = { nested: { value: 1 } };const copy = { ...original };copy.nested.value = 2; // 会修改原始对象
十二、Promise.all:并行请求优化
当需要同时发起多个异步请求时,Promise.all可显著提升性能。
对比示例:
// 串行请求(低效)async function sequentialFetch() {const res1 = await fetch('/api/data1');const res2 = await fetch('/api/data2');// ...}// 并行请求(高效)async function parallelFetch() {const [res1, res2] = await Promise.all([fetch('/api/data1'),fetch('/api/data2')]);}
十三、async/await错误处理:try/catch模式
使用async/await时,需通过try/catch捕获异步错误,避免未处理的Promise rejection。
最佳实践:
async function fetchData() {try {const response = await fetch('/api/data');const data = await response.json();return data;} catch (error) {console.error('Fetch failed:', error);throw error; // 可选择重新抛出或返回默认值}}
十四、防抖与节流:性能优化利器
通过函数防抖(debounce)和节流(throttle)控制高频事件(如resize、scroll)的触发频率。
防抖实现:
function debounce(fn, delay) {let timer;return function(...args) {clearTimeout(timer);timer = setTimeout(() => fn.apply(this, args), delay);};}window.addEventListener('resize', debounce(handleResize, 200));
十五、自定义Hook:React状态逻辑复用
在React应用中,通过自定义Hook封装可复用的状态逻辑(需配合React环境)。
示例Hook:
function useCounter(initialValue = 0) {const [count, setCount] = useState(initialValue);const increment = () => setCount(c => c + 1);const decrement = () => setCount(c => c - 1);return { count, increment, decrement };}// 使用function CounterComponent() {const { count, increment } = useCounter();return <button onClick={increment}>{count}</button>;}
总结
本文介绍的15个JavaScript技巧覆盖了从基础语法到高级模式的多个层面,开发者可根据实际需求选择合适的方案。掌握这些技巧不仅能提升代码质量,还能显著减少开发过程中的常见错误。建议在实际项目中逐步应用这些模式,并通过代码审查和性能测试验证其效果。