作为前端开发者,我们每天都在追求优雅、高效的解决方案。那些看似微不足道的小技巧,往往能成为提升开发效率的「秘密武器」!本文整理了46个来源于真实项目经验的JavaScript实用小技巧,覆盖数组操作、字符串处理、对象操作等七大核心模块。
无论你是前端新手还是开发老鸟,这些小技巧都能帮你解决日常开发痛点,让代码更简洁高效。每个技巧都配有清晰易懂的代码示例,让你即学即用!
1. 快速判断数组是否包含指定元素
判断数组是否包含某个元素,除了常用的includes,还有some和every,适用于不同场景,尤其在处理对象数组时更灵活。
const arr = [1, 2, 3, { id: 4, name: "test" }];
// 1. 基础值判断:includes(推荐,简洁)
const hasNum2 = arr.includes(2); // true
const hasNum5 = arr.includes(5); // false
// 2. 对象属性判断:some(判断是否存在满足条件的元素)
const hasTargetObj = arr.some((item) => item.id === 4); // true
const hasNameTest = arr.some((item) => item.name === "test"); // true
// 3. 全量判断:every(判断所有元素是否都满足条件)
const allNumLessThan5 = arr.every(
(item) => typeof item === "number" && item < 5
); // false(因存在对象元素)
const allItemValid = arr.every((item) => item !== undefined && item !== null); // true
2. 多维数组扁平化
快速将多层嵌套的数组扁平化为一维数组。
const arr = [1, 2, 3, [4, [5, 6, [7,8]]]];
// 方式1:使用flat方法(简洁高效)
console.log(arr.flat(Infinity)); // [1, 2, 3, 4, 5, 6, 7, 8]
// 方式2:使用join和split(字符串方法)
console.log(arr.join().split(',')); // ["1", "2", "3", "4", "5", "6", "7", "8"]
// 方式3:使用toString和split
console.log(arr.toString().split(',')); // ["1", "2", "3", "4", "5", "6", "7", "8"]
3. 快速生成指定范围的数组
一句代码生成从1到100的数组,适用于循环和映射场景。
// 方式1:使用展开运算符和keys方法
const arr1 = [...Array(100).keys()].map(i => i + 1);
// 方式2:使用Array.from和映射函数
const arr2 = Array.from(Array(100), (_, i) => i + 1);
4. 数组去重
多种方法实现数组元素去重,适用于不同数据类型。
const arr = [1, 2, 2, 3, 4, 5, 5, 3];
// 方式1:使用Set(推荐,简洁高效)
const newArr1 = [...new Set(arr)];
// 方式2:使用reduce方法
const newArr2 = arr.reduce((prev, cur) => prev.includes(cur) ? prev : [...prev, cur], []);
5. 两个数组的交集和差集
快速获取两个数组的共同元素和不同元素。
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
// 获取交集
let intersect = [...a].filter(x => b.has(x)); // [2, 3]
// 获取差集(a中有但b中没有的元素)
let difference = [...a].filter(x => !b.has(x)); // [1]
6. 获取数组最大值和最小值
简洁地获取数组中的最大和最小数值。
let numbers = [1, 3, 5, 5, 6, -3, 10];
let max = Math.max(...numbers); // 10
let min = Math.min(...numbers); // -3
7. 删除数组末尾元素
通过修改数组长度来快速删除末尾元素。
let a = [1, 2, 4, 5];
a.length = a.length - 2; // a变为[1, 2]
二、JavaScript 字符串操作技巧
8. 字符串反转
快速反转字符串内容。
let str = 'hello world';
console.log([...str].reverse().join('')); // 'dlrow olleh'
9. 统计字符串中字符出现次数
统计字符串中每个字符出现的频率。
let str = 'aaabbbccddeegggggggllllssgjwd';
let strInfo = str.split('').reduce((p, c) => (p[c]++ || (p[c] = 1), p), {});
console.log(strInfo); // {a: 3, b: 3, c: 2, d: 3, e: 2, g: 8, l: 4, s: 2, j: 1, w: 1}
10. 字符串模板
使用模板字符串更优雅地拼接字符串。
const name = 'Alice';
console.log(`Hello, ${name}!`); // Hello, Alice!
三、JavaScript 对象操作技巧
11. 优雅处理对象默认值
当获取对象深层属性时,常因属性不存在导致Cannot read property 'xxx' of undefined错误。使用可选链操作符(?.)+空值合并运算符(??),可一行代码处理默认值,无需层层判断。
const user = { name: "张三", address: { city: "北京" } };
// 常规写法:层层判断,繁琐
const district = user.address && user.address.district ? user.address.district : "未知区域";
// 优化写法:可选链+空值合并,简洁
const districtOpt = user.address?.district ?? "未知区域"; // 未知区域
const street = user.address?.street ?? "未填写街道"; // 未填写街道
const age = user.age ?? 18; // 18(若user.age为0或false,仍会返回实际值,区别于||)
12. 比"||"操作符更优的"??"
空值合并运算符只在左侧为null或undefined时才返回右侧值,避免了||操作符对假值的误判。
let a = 0;
let b = a || 'default'; // 'default',因为0是假值
let c = a ?? 'default'; // 0,只有null或undefined才使用默认值
13. 对象解构赋值
快速从对象中提取属性。
const person = { firstName: 'John', lastName: 'Doe' };
const { firstName, lastName } = person;
console.log(firstName, lastName); // John Doe
14. 使用 Object.is() 作比较
更精确的对象比较方法。
Object.is(0, 0); // true
Object.is(+0, -0); // false
Object.is(NaN, NaN); // true
四、JavaScript 数字处理技巧
15. 数字金额千分位格式化
快速将大数字格式化为千分位显示。
let a = 123456789;
console.log(a.toLocaleString('en-US')); // 123,456,789
16. 数字补0操作
为数字添加前导零,常用于日期时间格式化。
const padZero1 = (num, len = 2) => (`0${num}`).slice(-len);
const padZero2 = (num, len = 2) => (`${num}`).padStart(len, '0');
console.log(padZero1(8)); // '08'
console.log(padZero2(78, 5)); // '00078'
17. 小数取整
多种方法实现小数取整,适用于不同场景。
let num = 123.456;
// 常用方法
console.log(parseInt(num)); // 123
// 按位或
console.log(num | 0); // 123
// 双按位非
console.log(~~num); // 123
// 左移操作符
console.log(num << 0); // 123
// 按位异或
console.log(num ^ 0); // 123
18. 双位操作符替代 Math.floor
使用双位操作符可替代Math.floor(),执行速度更快。
Math.floor(5.9) === 5; // true
// 简写后
~~5.9 === 5; // true
五、JavaScript 函数与闭包技巧
19. 快速交换两个变量的值
交换两个变量的值,无需定义临时变量。
// 1. 数组解构(推荐,支持任意数据类型)
let a = 10, b = 20;
[a, b] = [b, a];
console.log(a, b); // 20 10
// 2. 算术运算(仅适用于数字类型)
let x = 5, y = 8;
x = x + y; // x=13
y = x - y; // y=5(13-8)
x = x - y; // x=8(13-5)
console.log(x, y); // 8 5
20. 短路条件语句 "&&"
简化条件判断,当左侧为真时才执行右侧代码。
if (isTrue) {
callback();
}
// 以上代码等同于
isTrue && callback();
21. 三元运算符的简洁写法
更简洁的条件赋值方式。
const age = 25;
const message = age > 18 ? 'Adult' : 'Minor'; // 更简洁的条件赋值
22. 立即执行函数表达式 (IIFE)
定义后立即执行的函数,常用于创建独立作用域。
(function() {
console.log('Immediately executed!');
})();
23. 函数柯里化 (Currying)
将接受多个参数的函数转换为接受单一参数的函数序列。
function add(x) {
return function(y) {
return x + y;
};
}
const addFive = add(5);
console.log(addFive(10)); // 15
24. 闭包 (Closure) - 变量的「记忆宫殿」🏰
闭包就像一个神奇的记忆盒子,能帮你保存变量的状态,即使函数执行完毕也不会忘记~ 🧠
function counter() {
let count = 0; // 这个变量会被闭包「记住」
return function() {
return ++count;
};
}
const increment = counter();
console.log(increment()); // 1
console.log(increment()); // 2 - 看!它记得上次的结果
25. 剩余参数
处理不定数量的函数参数。
function sum(...args) {
return args.reduce((acc, val) => acc + val, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
26. 箭头函数
简化函数定义,尤其适合用作回调函数。
const multiply = (a, b) => a * b;
console.log(multiply(3, 4)); // 12
27. Promise 链式调用
更优雅地处理异步操作。
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
28. 递归
函数调用自身解决问题,适用于树形结构遍历等场景。
function factorial(n) {
return n <= 1 ? 1 : n * factorial(n - 1);
}
console.log(factorial(5)); // 120
六、CSS 样式优化技巧
29. 实现元素 "垂直居中" 的高效方式
垂直居中是前端高频需求,以下几种方式覆盖大多数情况,且兼容性良好。
/* 场景1:已知子元素高度(固定高度) */
.parent1 {
position: relative;
height: 300px;
border: 1px solid #eee;
}
.child1 {
position: absolute;
top: 50%;
left: 50%;
width: 200px;
height: 100px;
margin-top: -50px; /* 自身高度的一半 */
margin-left: -100px; /* 自身宽度的一半 */
background: #4285f4;
}
/* 场景2:未知子元素高度(通用方案) */
.parent2 {
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
height: 300px;
border: 1px solid #eee;
}
.child2 {
background: #ea4335;
padding: 20px;
}
/* 场景3:文本垂直居中(单行/多行通用) */
.text-container {
display: flex;
align-items: center;
height: 100px;
border: 1px solid #eee;
}
.text-content {
line-height: 1.5; /* 多行文本需重置line-height,避免行高过大 */
}
30. 用 "CSS 渐变" 替代简单背景图
简单的背景色过渡、条纹效果,无需切图,用 CSS 渐变即可实现,减少 HTTP 请求,提升页面加载速度。
/* 1. 线性渐变:从左到右的颜色过渡 */
.gradient-btn {
background: linear-gradient(to right, #4285f4, #ea4335);
color: white;
border: none;
padding: 8px16px;
border-radius: 4px;
cursor: pointer;
}
/* 2. 重复线性渐变:条纹背景 */
.striped-bg {
background: repeating-linear-gradient(
45deg,
#f5f5f5,
#f5f5f5 10px,
#eee 10px,
#eee 20px
);
height: 200px;
width: 100%;
}
/* 3. 径向渐变:圆形渐变背景 */
.circle-gradient {
background: radial-gradient(circle, #4285f4 0%, #3367d6 100%);
width: 100px;
height: 100px;
border-radius: 50%;
}
七、业务场景处理技巧
31. 表单 "防抖提交":避免重复点击提交
表单提交时,用户可能因网络延迟重复点击提交按钮,导致多次请求。用防抖函数可限制一定时间内只能提交一次,且不影响正常提交体验。
// 1. 防抖函数(可复用)
function debounce(func, delay = 1000) {
let timer = null;
returnfunction (...args) {
if (timer) clearTimeout(timer);
// 延迟delay毫秒执行,期间重复点击会重置定时器
timer = setTimeout(() => {
func.apply(this, args);
timer = null;
}, delay);
};
}
// 2. 表单提交函数
function submitForm() {
const formData = {
username: document.getElementById("username").value,
password: document.getElementById("password").value,
};
// 模拟接口请求
console.log("提交表单数据:", formData);
// axios.post('/api/login', formData).then(res => { ... });
}
// 3. 给提交按钮绑定防抖后的提交事件
const submitBtn = document.getElementById("submit-btn");
submitBtn.addEventListener("click", debounce(submitForm, 1500)); // 1.5秒内只能提交一次
32. 快速实现 "点击空白处关闭弹窗" 功能
弹窗组件是前端常用组件,"点击空白处关闭弹窗" 是核心交互之一。通过判断点击事件的目标元素是否在弹窗内部,可轻松实现该功能。
<!-- 弹窗HTML结构 -->
<div class="modal" id="modal">
<div class="modal-content">
<h3>弹窗标题</h3>
<p>弹窗内容...</p>
<button class="close-btn" id="closeBtn">关闭</button>
</div>
</div>
<button id="openBtn">打开弹窗</button>
/* 弹窗样式 */
.modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: none; /* 默认隐藏 */
justify-content: center;
align-items: center;
}
.modal.show {
display: flex; /* 显示弹窗 */
}
.modal-content {
width: 300px;
background: white;
padding: 20px;
border-radius: 4px;
position: relative;
}
.close-btn {
margin-top: 10px;
padding: 6px14px;
background: #ea4335;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
// 弹窗控制逻辑
const modal = document.getElementById("modal");
const openBtn = document.getElementById("openBtn");
const closeBtn = document.getElementById("closeBtn");
const modalContent = document.querySelector(".modal-content");
// 打开弹窗
openBtn.addEventListener("click", () => {
modal.classList.add("show");
});
// 关闭弹窗(通用函数)
function closeModal() {
modal.classList.remove("show");
}
// 点击关闭按钮关闭弹窗
closeBtn.addEventListener("click", closeModal);
// 点击空白处关闭弹窗
modal.addEventListener("click", (e) => {
// 判断点击的是弹窗背景(modal),而非弹窗内容(modalContent)
if (e.target === modal) {
closeModal();
}
});
33. 解决 "iOS 端输入框聚焦时页面上移" 问题
iOS Safari 浏览器中,输入框(input/textarea)聚焦时,页面常会莫名上移且失焦后不回落,影响用户体验。通过监听输入框焦点事件,可强制页面回正。
// 解决iOS输入框聚焦后页面上移问题
const inputs = document.querySelectorAll("input, textarea");
inputs.forEach((input) => {
// 失焦时强制页面滚动到顶部(或指定位置)
input.addEventListener("blur", () => {
window.scrollTo({
top: 0,
left: 0,
behavior: "smooth", // 平滑滚动,可选
});
});
// 聚焦时也可微调位置(根据需求可选)
input.addEventListener("focus", () => {
setTimeout(() => {
input.scrollIntoViewIfNeeded(false); // false表示不居中,避免页面偏移
}, 100);
});
});
34. 位运算:检查一个数是否为2的幂
利用位运算的特性,高效判断一个数是否为2的幂。
// 检查一个数是否为2的幂
function isPowerOfTwo(n) {
return n > 0 && (n & (n - 1)) === 0;
}
console.log(isPowerOfTwo(16)); // true
console.log(isPowerOfTwo(18)); // false
35. 使用 Array.from 或 Array.of 创建数组
更灵活地创建数组。
// 从Set创建数组并自动去重
const arrayFromSet = Array.from(new Set([1, 2, 2, 3]));
console.log(arrayFromSet); // [1, 2, 3]
// 创建包含单个元素的数组(避免Array构造函数的陷阱)
const arrayWithOneElement = Array.of(42);
console.log(arrayWithOneElement); // [42]
36. 隐式转义(字符串转数字)
使用一元加号操作符快速将字符串转换为数字。
let a = '1';
console.log(Number(a)); // 1
console.log(+a); // 1(更简洁)
37. 深拷贝对象的多种方法
在前端开发中,我们经常需要复制对象但又不想影响原对象,这时就需要深拷贝技术。
const obj = { name: 'John', address: { city: 'New York' }, hobbies: ['reading', 'coding'] };
// 方法1:使用JSON序列化与反序列化(简单对象推荐)
const deepCopy1 = JSON.parse(JSON.stringify(obj));
// 注意:此方法无法复制函数、循环引用对象、特殊对象(如Date、RegExp等)
// 方法2:递归实现深拷贝(适用于复杂对象)
function deepClone(source) {
if (source === null || typeof source !== 'object') return source;
if (source instanceofDate) returnnewDate(source);
if (source instanceofRegExp) returnnewRegExp(source);
if (Array.isArray(source)) {
return source.map(item => deepClone(item));
}
const target = {};
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = deepClone(source[key]);
}
}
return target;
}
const deepCopy2 = deepClone(obj);
// 方法3:使用第三方库(如Lodash)
// const deepCopy3 = _.cloneDeep(obj);
38. 优雅地合并多个对象
快速合并多个对象的属性,覆盖冲突的值。
const obj1 = { name: 'Alice', age: 25 };
const obj2 = { age: 26, city: 'New York' };
const obj3 = { hobby: 'reading', city: 'Boston' };
// ES6+ 展开运算符
const mergedObj1 = { ...obj1, ...obj2, ...obj3 };
console.log(mergedObj1); // { name: 'Alice', age: 26, city: 'Boston', hobby: 'reading' }
// Object.assign 方法
const mergedObj2 = Object.assign({}, obj1, obj2, obj3);
console.log(mergedObj2); // { name: 'Alice', age: 26, city: 'Boston', hobby: 'reading' }
// ES2022 Object.groupBy 对数组元素分组
const people = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 30 },
{ name: 'Charlie', age: 25 }
];
const groupedByAge = Object.groupBy(people, person => person.age);
console.log(groupedByAge);
// { '25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }], '30': [{ name: 'Bob', age: 30 }] }
39. 使用 async/await 处理异步操作
现代JavaScript中处理异步操作的优雅方式。
// 基础用法
asyncfunction fetchData() {
try {
const response = await fetch('https://api.example.com/data');
if (!response.ok) thrownewError('Network response was not ok');
const data = await response.json();
return data;
} catch (error) {
console.error('Error fetching data:', error);
}
}
// 并行执行多个异步操作
asyncfunction fetchMultipleData() {
const [userData, productData, orderData] = awaitPromise.all([
fetch('/api/users'),
fetch('/api/products'),
fetch('/api/orders')
]);
const [users, products, orders] = awaitPromise.all([
userData.json(),
productData.json(),
orderData.json()
]);
return { users, products, orders };
}
40. 防抖与节流的更精确实现
完善防抖与节流的实现,适用于不同场景。
// 防抖:事件触发后n秒再执行回调,若在n秒内再次触发则重新计时
function debounce(fn, delay) {
let timer = null;
returnfunction(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
// 节流:规定在一个单位时间内,只能触发一次函数
function throttle(fn, delay) {
let lastTime = 0;
returnfunction(...args) {
const nowTime = Date.now();
if (nowTime - lastTime >= delay) {
fn.apply(this, args);
lastTime = nowTime;
}
};
}
// 带leading和trailing选项的节流函数
function advancedThrottle(fn, delay, options = {}) {
const { leading = true, trailing = true } = options;
let timer = null;
let lastTime = 0;
returnfunction(...args) {
const nowTime = Date.now();
// 第一次调用是否执行
if (!lastTime && !leading) lastTime = nowTime;
// 计算剩余时间
const remainingTime = delay - (nowTime - lastTime);
if (remainingTime <= 0) {
// 执行函数并重置定时器
if (timer) {
clearTimeout(timer);
timer = null;
}
fn.apply(this, args);
lastTime = nowTime;
} elseif (trailing && !timer) {
// 最后一次调用时,确保执行
timer = setTimeout(() => {
fn.apply(this, args);
lastTime = !leading ? 0 : Date.now();
timer = null;
}, remainingTime);
}
};
}
41. 更高效的DOM操作技巧
减少DOM操作,提升页面性能。
// 1. 使用文档片段减少重排重绘
function appendMultipleElements(container, elements) {
const fragment = document.createDocumentFragment();
elements.forEach(element => {
fragment.appendChild(element);
});
container.appendChild(fragment); // 只触发一次重排
}
// 2. 批量修改DOM时先脱离文档流
function batchUpdateElement(element, updates) {
// 克隆元素或隐藏元素
const clone = element.cloneNode(true);
// 在克隆上执行所有修改
updates.forEach(updateFn => updateFn(clone));
// 一次性替换原元素
element.parentNode.replaceChild(clone, element);
}
// 3. 优化事件委托
function delegateEvents(parent, selector, eventType, handler) {
parent.addEventListener(eventType, function(event) {
const target = event.target.closest(selector);
if (target && parent.contains(target)) {
handler.call(target, event);
}
});
}
42. 数组的高级排序与过滤
使用自定义比较函数对数组进行高级排序和过滤。
// 1. 对象数组按属性排序
const users = [
{ name: 'Alice', age: 25 },
{ name: 'Bob', age: 20 },
{ name: 'Charlie', age: 30 }
];
// 按年龄升序
const sortedByAgeAsc = [...users].sort((a, b) => a.age - b.age);
// 按名字字母顺序
const sortedByName = [...users].sort((a, b) => a.name.localeCompare(b.name));
// 2. 按多个条件排序
const products = [
{ category: 'fruit', price: 5 },
{ category: 'vegetable', price: 3 },
{ category: 'fruit', price: 2 },
{ category: 'vegetable', price: 4 }
];
// 先按类别排序,再按价格排序
const sortedProducts = [...products].sort((a, b) => {
if (a.category !== b.category) {
return a.category.localeCompare(b.category);
}
return a.price - b.price;
});
// 3. 数组过滤的高级用法
const mixedArray = [1, '2', 3, '4', null, undefined, true, false];
// 仅保留数字
const numbersOnly = mixedArray.filter(item =>typeof item === 'number');
// 仅保留真值
const truthyValues = mixedArray.filter(Boolean);
// 分页获取数据
const largeArray = Array.from({length: 100}, (_, i) => i + 1); // 假设有100条数据
const pageSize = 10;
const page = 2;
const paginatedData = largeArray.slice((page - 1) * pageSize, page * pageSize);
43. 使用Map和Set提升数据处理效率
利用ES6的Map和Set数据结构优化数据操作。
// 1. 使用Map优化查找性能
const usersWithId = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 20 },
{ id: 3, name: 'Charlie', age: 30 }
];
const userMap = newMap();
usersWithId.forEach(user => userMap.set(user.id, user));
// O(1)时间复杂度查找用户 - 比循环遍历快多啦!⚡
const getUserById = id => userMap.get(id);
// 2. 高效处理唯一值集合
const tags = ['javascript', 'html', 'css', 'javascript', 'react'];
const uniqueTags = newSet(tags);
console.log([...uniqueTags]); // ['javascript', 'html', 'css', 'react']
// 3. 使用WeakMap避免内存泄漏
// 存储DOM元素的相关数据,不会阻止垃圾回收
const elementData = newWeakMap();
function storeElementInfo(element, info) {
elementData.set(element, info);
}
function getElementInfo(element) {
return elementData.get(element);
}
44. 条件渲染的高级技巧
在JavaScript中处理复杂的条件渲染逻辑。
// 1. 使用对象映射替代switch语句
function getGreeting(hour) {
const greetings = {
morning: 'Good morning!',
afternoon: 'Good afternoon!',
evening: 'Good evening!'
};
const timeOfDay = hour < 12 ? 'morning' : hour < 18 ? 'afternoon' : 'evening';
return greetings[timeOfDay];
}
// 2. 条件组合的短路评估
function canAccessFeature(user, feature) {
// 多重条件检查,任一不满足则返回false
return user.isLoggedIn &&
user.permissions.includes(feature) &&
!user.isLocked &&
feature.isActive;
}
// 3. 使用数组实现多选一逻辑
function getComponent(type) {
const components = [
{ type: 'button', component: ButtonComponent },
{ type: 'input', component: InputComponent },
{ type: 'select', component: SelectComponent }
];
return components.find(comp => comp.type === type)?.component || DefaultComponent;
}
45. 移动端触摸事件处理
优化移动端触摸交互体验。
// 1. 简单的触摸滑动检测
let touchStartX = 0;
let touchEndX = 0;
const threshold = 50; // 最小滑动距离
function handleTouchStart(e) {
touchStartX = e.changedTouches[0].screenX;
}
function handleTouchEnd(e) {
touchEndX = e.changedTouches[0].screenX;
handleSwipe();
}
function handleSwipe() {
if (touchEndX < touchStartX - threshold) {
console.log('向左滑动');
} elseif (touchEndX > touchStartX + threshold) {
console.log('向右滑动');
}
}
// 2. 长按事件检测
let longPressTimer;
const longPressThreshold = 800; // 长按触发时间阈值(毫秒)
function handleTouchStartLongPress(e) {
longPressTimer = setTimeout(() => {
console.log('长按触发');
// 执行长按操作
}, longPressThreshold);
}
function handleTouchEndLongPress() {
clearTimeout(longPressTimer);
}
// 为元素添加事件监听
element.addEventListener('touchstart', handleTouchStart);
element.addEventListener('touchend', handleTouchEnd);
element.addEventListener('touchstart', handleTouchStartLongPress);
element.addEventListener('touchend', handleTouchEndLongPress);
element.addEventListener('touchmove', handleTouchEndLongPress); // 移动时取消长按
46. 错误处理与日志记录
优雅地处理JavaScript错误并记录关键信息。
// 1. 全局错误捕获
window.addEventListener('error', function(e) {
console.error('全局错误:', e.error);
// 可以发送错误信息到服务器
// reportErrorToServer({ message: e.error.message, stack: e.error.stack });
});
// 2. Promise错误捕获
window.addEventListener('unhandledrejection', function(e) {
console.error('未处理的Promise错误:', e.reason);
// 可以发送错误信息到服务器
});
// 3. 封装try-catch,简化错误处理
function safeExecute(fn, fallbackValue = null) {
try {
return fn();
} catch (error) {
console.error('执行出错:', error);
return fallbackValue;
}
}
// 使用示例
const jsonString = '{"name":"John","age":30}';
const result = safeExecute(() =>JSON.parse(jsonString), {});
// 4. 分级日志记录
const logger = {
debug: (...args) => {
if (process.env.NODE_ENV !== 'production') {
console.log('[DEBUG]', ...args);
}
},
info: (...args) =>console.info('[INFO]', ...args),
warn: (...args) =>console.warn('[WARN]', ...args),
error: (...args) => {
console.error('[ERROR]', ...args);
// 可以选择在此处发送错误报告
}
};
// 使用示例
logger.info('应用启动');
logger.warn('API调用超时');
const error = newError('网络请求失败');
logger.error('请求失败', error);
🎉 总结:小技巧带来大提升
以上46个JavaScript实用小技巧,就像开发道路上的46颗小星星 ✨,照亮你解决问题的思路!它们覆盖了前端开发中数组操作、字符串处理、对象操作、数字计算、函数设计、CSS样式和实际业务场景等多个维度,共同特点是:
- 简洁高效:用更少的代码解决问题,少写一行是一行!📝
- 实用性强:聚焦日常开发高频痛点,学完即可复制粘贴用起来!👨💻
- 兼容性好:避免使用过于前沿的API,确保在主流浏览器中都能正常运行~ 🌐
- 性能优化:通过更优的实现方式提升代码执行效率,让你的应用跑得更快!⚡
前端开发的核心是"高效解决问题",这些小技巧看似简单,却能在实际开发中帮你节省大量时间,避免不必要的踩坑。建议将这些技巧收藏起来,融入日常开发习惯,同时也可以根据实际需求灵活调整,举一反三,解决更多复杂场景的问题。
希望这些小技巧能让你的前端开发之路更加顺畅愉快!Happy Coding! 🎊
阅读原文:原文链接
该文章在 2026/1/6 18:25:17 编辑过