文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
JavaScript 是一种功能强大的语言,对于现代 Web 开发至关重要。今天我将分享一些超级实用的JavaScript技巧,它们将使你成为更高效、更有效的 JavaScript 开发人员,每个技巧都有详细的解释和示例。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
1. 使用 `let` 和 `const` 代替 `var`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:`var` 具有函数作用域,这可能导致错误和不可预测的行为。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用具有块作用域的 `let` 和 `const`。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmllet count = 0;
const PI = 3.14;
使用 `let` 和 `const` 有助于防止与作用域相关的错误,因为它确保变量只能在定义的块内访问。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
2. 默认参数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:如果没有提供参数,函数可能会失败。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用默认参数设置后备值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction greet(name = 'Guest') {
return `Hello, ${name}!`;
}
console.log(greet()); // "Hello, Guest!"
默认参数确保函数具有合理的默认值,从而防止错误并使代码更加健壮。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
3. 模板文字文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:字符串连接可能很麻烦且容易出错。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用模板文字进行更清晰、更易读的字符串插值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst name = 'John';
const greeting = `Hello, ${name}!`;
console.log(greeting); // "Hello, John!"
模板文字使创建带有嵌入表达式和多行字符串的字符串变得更加容易。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
4. 解构赋值文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:从对象和数组中提取值可能非常冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用解构赋值更简洁地提取值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst user = { name: 'Jane', age: 25 };
const { name, age } = user;
console.log(name, age); // "Jane" 25
解构赋值允许你轻松地将对象中的属性和数组中的元素提取到不同的变量中。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
5. 箭头函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:传统函数表达式可能很冗长,并且不会在词汇上绑定“this”。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用箭头函数来实现更短的语法和词汇“this”。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst add = (a, b) => a + b;
console.log(add(2, 3)); // 5
箭头函数为函数表达式提供了简洁的语法,并确保 `this` 在词汇上是绑定的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
6. 扩展运算符文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:组合数组或对象可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用扩展运算符可以轻松组合数组和对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combined = […arr1, …arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]
扩展运算符允许你将一个数组或对象的元素扩展到另一个数组或对象中。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
7. 剩余参数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:处理可变数量的函数参数可能很棘手。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用剩余参数捕获数组中的所有参数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
function sum(…args) {
return args.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
剩余参数允许你将无限数量的参数作为数组处理,从而使你的函数更加灵活。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
8. 短路求值文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:编写条件语句可能很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用短路求值编写简洁的条件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst isLoggedIn = true;
const user = isLoggedIn && { name: 'Jane', age: 25 };
console.log(user); // { name: 'Jane', age: 25 }
短路求值使用逻辑运算符 `&&` 和 `||` 来简化条件表达式。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
9. 可选链文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:如果链中的任何部分为 `null` 或 `undefined`,则访问深层嵌套的属性可能会导致错误。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用可选链安全地访问嵌套属性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst user = { profile: { name: 'Jane' } };
const userName = user?.profile?.name;
console.log(userName); // "Jane"
可选链式连接允许你安全地访问嵌套属性,而无需明确检查链式连接的每一级是否为 `null` 或 `undefined`。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
10. 空值合并文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:如果值为 `0` 或 `””`,则使用 `||` 提供默认值可能会产生意外结果。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:仅在 `null` 或 `undefined` 时使用空值合并 (`??`) 提供默认值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst user = { name: '', age: 0 };
const userName = user.name ?? 'Anonymous';
const userAge = user.age ?? 18;
console.log(userName); // ""
console.log(userAge); // 0
空值合并仅允许在左侧为“null”或“undefined”时提供默认值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
11. 对象属性简写文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:将变量分配给对象属性可能会重复。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用属性简写来简化对象创建。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst name = 'Jane';
const age = 25;
const user = { name, age };
console.log(user); // { name: 'Jane', age: 25 }
属性简写允许你在属性名称与变量名称匹配时省略属性名称,从而使代码更简洁。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
12. 动态属性名称文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:使用动态属性名称创建对象可能很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用计算属性名称动态创建对象属性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst propName = 'age';
const user = { name: 'Jane', [propName]: 25 };
console.log(user); // { name: 'Jane', age: 25 }
计算属性名称允许你动态创建对象属性,使用表达式的值作为属性名称。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
13. 数组 `map()`、`filter()` 和 `reduce()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:迭代数组以转换、过滤或累积值可能会重复。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `map()`、`filter()` 和 `reduce()` 进行常见的数组操作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15
这些数组方法提供了一种转换、过滤和减少数组的函数式方法,使你的代码更具表现力和简洁性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
14. 字符串 `includes()`、`startsWith()` 和 `endsWith()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:检查字符串是否包含、以子字符串开头或以子字符串结尾可能很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `includes()`、`startsWith()` 和 `endsWith()` 进行更简单的字符串检查。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst str = 'Hello, world!';
console.log(str.includes('world')); // true
console.log(str.startsWith('Hello')); // true
console.log(str.endsWith('!')); // true
这些字符串方法提供了一种简单易读的方法来检查子字符串的存在、开始或结束。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
15. 函数参数中的数组和对象解构文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:从作为函数参数传递的数组或对象中提取值可能很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:在函数参数中使用解构来直接提取值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst user = { name: 'Jane', age: 25 };
function greet({ name, age }) {
return `Hello, ${name}! You are ${age} years old.`;
}
console.log(greet(user)); // "Hello, Jane! You are 25 years old."
函数参数中的解构允许你直接从传递给函数的对象或数组中提取值,从而使代码更简洁、更易读。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
16. 解构中的默认值文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:解构对象时处理缺失的属性可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:在解构中使用默认值来提供后备值。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst user = { name: 'Jane' };
const { name, age = 18 } = user;
console.log(name); // "Jane"
console.log(age); // 18
解构中的默认值允许你为可能缺失的属性提供后备值,从而使你的代码更加健壮。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
17. 对象 `assign()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:克隆或合并对象可能很冗长且容易出错。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `Object.assign()` 克隆或合并对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst target = { a: 1 };
const source = { b: 2 };
const merged = Object.assign(target, source);
console.log(merged); // { a: 1, b: 2 }
`Object.assign()` 允许你高效地克隆或合并对象,从而减少手动复制的需要。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
18. 数组 `find()` 和 `findIndex()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:使用循环在数组中查找元素或其索引可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `find()` 和 `findIndex()` 使代码更易读。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst users = [
{ id: 1, name: 'Jane' },
{ id: 2, name: 'John' },
];
const user = users.find(u => u.id === 1);
console.log(user); // { id: 1, name: 'Jane' }
const index = users.findIndex(u => u.id === 1);
console.log(index); // 0
这些数组方法提供了一种根据条件查找元素或其索引的简单方法,从而提高了代码的可读性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
19. 数组 `some()` 和 `every()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:检查数组中的部分或全部元素是否满足条件可能会很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `some()` 和 `every()` 来获得更简洁的代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst numbers = [1, 2, 3, 4, 5];
const hasEven = numbers.some(num => num % 2 === 0);
console.log(hasEven); // true
const allEven = numbers.every(num => num % 2 === 0);
console.log(allEven); // false
这些数组方法允许你以简洁的方式检查数组中的部分或全部元素是否满足条件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
20. 数组 `flat()` 和 `flatMap()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:展平嵌套数组或映射和展平数组可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `flat()` 和 `flatMap()` 使代码更易读。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst nested = [1, [2, [3, [4]]]];
const flat = nested.flat(2);
console.log(flat); // [1, 2, 3, [4]]
const mapped = [1, 2, 3].flatMap(x => [x, x * 2]);
console.log(mapped); // [1, 2, 2, 4, 3, 6]
这些数组方法提供了一种简单的方法来展平嵌套数组,并在一个步骤中映射和展平。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
21. 数组 `from()` 和 `of()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:从可迭代对象或参数创建数组可能很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `Array.from()` 和 `Array.of()` 获得更简洁的代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst set = new Set([1, 2, 3]);
const arrFromSet = Array.from(set);
console.log(arrFromSet); // [1, 2, 3]
const arrOfNumbers = Array.of(1, 2, 3);
console.log(arrOfNumbers); // [1, 2, 3]
`Array.from()` 允许你从可迭代对象创建数组,而 `Array.of()` 允许你从参数列表创建数组。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
22. 回调中的参数解构文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:访问传递给回调的对象的属性可能很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:在回调参数中使用解构以获得更简洁的代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst users = [
{ id: 1, name: 'Jane' },
{ id: 2, name: 'John' },
];
users.forEach(({ id, name }) => {
console.log(`User ID: ${id}, User Name: ${name}`);
});
回调参数中的解构允许你直接访问传递给回调的对象的属性,从而使代码更简洁。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
23. 可选回调函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:处理可选回调函数可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用短路求值来调用可选回调。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction fetchData(url, callback) {
fetch(url)
.then(response => response.json())
.then(data => {
callback && callback(data);
});
}
短路求值允许您仅在提供可选回调函数时才调用该函数,从而使代码更加健壮。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
24. Promisify 回调文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:将基于回调的函数转换为promises可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用实用函数来 promisify 回调。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction promisify(fn) {
return function (…args) {
return new Promise((resolve, reject) => {
fn(…args, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
};
}
const readFile = promisify(require('fs').readFile);
readFile('path/to/file.txt', 'utf8')
.then(data => console.log(data))
.catch(err => console.error(err));
Promisifying 允许你将基于回调的函数转换为promises,从而更轻松地使用 async/await 语法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
25. 用于类似同步代码的 Async/Await文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:使用promises编写异步代码可能冗长且难以阅读。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 async/await 以同步风格编写异步代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlasync function fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
console.log(data);
} catch (error) {
console.error('Error fetching data:', error);
}
}
fetchData('https://api.example.com/data');
Async/await 提供了一种编写外观和行为都像同步代码的异步代码的方法,从而提高了可读性和可维护性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
26. 链接承诺文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:按顺序处理多个异步操作可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:链式承诺处理多个异步操作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
console.log('Data:', data);
return fetch('https://api.example.com/more-data');
})
.then(response => response.json())
.then(moreData => {
console.log('More Data:', moreData);
})
.catch(error => {
console.error('Error:', error);
});
链接 Promise 可让你按顺序处理多个异步操作,从而提高可读性和可维护性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
27. Promise.all 用于并发执行文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:同时处理多个异步操作可能具有挑战性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `Promise.all` 来处理并发异步操作。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst fetchData1 = fetch('https://api.example.com/data1').then(response => response.json());
const fetchData2 = fetch('https://api.example.com/data2').then(response => response.json());
Promise.all([fetchData1, fetchData2])
.then(([data1, data2]) => {
console.log('Data 1:', data1);
console.log('Data 2:', data2);
})
.catch(error => {
console.error('Error:', error);
});
`Promise.all` 允许你同时处理多个异步操作,并在所有操作完成后继续执行。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
28. 防抖动函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:频繁的函数调用(例如在窗口调整大小事件期间)会降低性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用防抖动函数来限制函数执行的速率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction debounce(func, wait) {
let timeout;
return function (…args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
window.addEventListener('resize', debounce(() => {
console.log('Window resized');
}, 200));
防抖动函数可确保函数仅在一段时间不活动后才被调用,从而提高性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
29. 节流阀函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:限制频繁触发的事件(如滚动或调整大小)的函数执行速率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用节流阀函数来限制函数的执行速率。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction throttle(func, limit) {
let lastFunc;
let lastRan;
return function (…args) {
if (!lastRan) {
func.apply(this, args);
lastRan = Date.now();
} else {
clearTimeout(lastFunc);
lastFunc = setTimeout(() => {
if (Date.now() - lastRan >= limit) {
func.apply(this, args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
window.addEventListener('scroll', throttle(() => {
console.log('Window scrolled');
}, 200));
节流函数可确保在指定时间段内最多只调用一次函数,从而提高频繁触发事件的性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
30. 深度克隆对象文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:克隆嵌套对象可能很棘手且容易出错。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用结构化克隆或 Lodash 等库来深度克隆对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst obj = { a: 1, b: { c: 2 } };
const deepClone = JSON.parse(JSON.stringify(obj));
console.log(deepClone); // { a: 1, b: { c: 2 } }
深度克隆确保嵌套对象按值复制,而不是按引用复制,从而防止对原始对象进行意外修改。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
31. 记忆化文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:反复调用昂贵的函数会降低性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用记忆化来缓存昂贵的函数调用的结果。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction memoize(func) {
const cache = new Map();
return function (…args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = func.apply(this, args);
cache.set(key, result);
return result;
};
}
const expensiveFunction = memoize((num) => {
console.log('Computing…');
return num * 2;
});
console.log(expensiveFunction(2)); // "Comput
ing…" 4
console.log(expensiveFunction(2)); // 4
记忆化通过缓存昂贵的函数调用结果并返回缓存的结果以供后续具有相同参数的调用来提高性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
32. 柯里化函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:创建具有多个参数的函数可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用柯里化创建具有部分应用参数的函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction curry(func) {
return function curried(…args) {
if (args.length >= func.length) {
return func.apply(this, args);
}
return function (…nextArgs) {
return curried.apply(this, args.concat(nextArgs));
};
};
}
const sum = (a, b, c) => a + b + c;
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6
通过柯里化,你可以创建可以用较少参数调用的函数,并返回接受其余参数的新函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
33. 部分应用文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:调用带有重复参数的函数可能很繁琐。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用部分应用将一些参数预先应用于函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction partial(func, …presetArgs) {
return function (…laterArgs) {
return func(…presetArgs, …laterArgs);
};
}
const multiply = (a, b, c) => a * b * c;
const double = partial(multiply, 2);
console.log(double(3, 4)); // 24
部分应用允许你通过预先应用一些参数来创建新函数,从而使你的代码更加灵活和可重用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
34. 函数组合文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:将多个函数组合成一个操作可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用函数组合来组合多个函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst compose = (…funcs) => (arg) =>
funcs.reduceRight((prev, fn) => fn(prev), arg);
const add = (x) => x + 1;
const multiply = (x) => x * 2;
const addThenMultiply = compose(multiply, add);
console.log(addThenMultiply(5)); // 12
函数组合允许你通过组合多个函数来创建新函数,从而使你的代码更加模块化和可重用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
35. 函数流水线文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:将一系列函数应用于一个值可能会很冗长。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用函数流水线按顺序应用一系列函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst pipe = (…funcs) => (arg) =>
funcs.reduce((prev, fn) => fn(prev), arg);
const add = (x) => x + 1;
const multiply = (x) => x * 2;
const addThenMultiply = pipe(add, multiply);
console.log(addThenMultiply(5)); // 12
函数流水线允许你按顺序将一系列函数应用于一个值,从而提高代码的可读性和可维护性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
36. 自调用函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:定义后立即执行函数可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用立即调用函数表达式 (IIFE)。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html(function () {
console.log('This runs immediately!');
})();
IIFE 允许你在定义后立即执行函数,这对于创建隔离范围和避免污染全局命名空间非常有用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
37. 避免使用全局变量文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:全局变量可能导致冲突和意外的副作用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用局部变量和模块来避免污染全局命名空间。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html// Using local variables
function doSomething() {
let localVariable = 'This is local';
console.log(localVariable);
}
// Using modules
const myModule = (function () {
let privateVariable = 'This is private';
return {
publicMethod() {
console.log(privateVariable);
},
};
})();
myModule.publicMethod(); // "This is private"
避免使用全局变量有助于防止冲突和意外副作用,从而使你的代码更加模块化和易于维护。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
38. 使用闭包进行封装文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:暴露函数的内部细节可能会导致误用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用闭包封装内部细节。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction createCounter() {
let count = 0;
return {
increment() {
count++;
return count;
},
decrement() {
count - ;
return count;
},
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.decrement()); // 1
闭包允许你封装内部细节并仅公开必要的功能,从而提高代码的安全性和可维护性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
39. 模块模式文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:将代码组织成可重用的模块可能具有挑战性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用模块模式创建可重用和封装的代码。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst myModule = (function () {
let privateVariable = 'This is private';
function privateMethod() {
console.log(privateVariable);
}
return {
publicMethod() {
privateMethod();
},
};
})();
myModule.publicMethod(); // "This is private"
模块模式允许你创建可重用和封装的代码,从而改善代码组织和可维护性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
40. 单例模式文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:确保只创建一个类的实例可能具有挑战性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用单例模式创建单个实例。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst singleton = (function () {
let instance;
function createInstance() {
return {
name: 'Singleton Instance',
};
}
return {
getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
},
};
})();
const instance1 = singleton.getInstance();
const instance2 = singleton.getInstance();
console.log(instance1 === instance2); // true
单例模式确保只创建一个类的实例,这对于管理共享资源或配置很有用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
41. 工厂模式文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:创建具有复杂初始化的对象可能很麻烦。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用工厂模式创建对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction createUser(name, role) {
return {
name,
role,
sayHello() {
console.log(`Hello, my name is ${this.name} and I am a ${this.role}`);
},
};
}
const admin = createUser('Alice', 'admin');
const user = createUser('Bob', 'user');
admin.sayHello(); // "Hello, my name is Alice and I am an admin"
user.sayHello(); // "Hello, my name is Bob and I am a user"
工厂模式允许你以灵活且可重用的方式创建具有复杂初始化的对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
42. 观察者模式文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:管理状态变化和通知多个组件可能具有挑战性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用观察者模式来管理状态变化并通知观察者。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlfunction Subject() {
this.observers = [];
}
Subject.prototype = {
subscribe(observer) {
this.observers.push(observer);
},
unsubscribe(observer) {
this.observers = this.observers.filter((obs) => obs !== observer);
},
notify(data) {
this.observers.forEach((observer) => observer.update(data));
},
};
function Observer(name) {
this.name = name;
}
Observer.prototype.update = function (data) {
console.log(`${this.name} received data: ${data}`);
};
const subject = new Subject();
const observer1 = new Observer('Observer 1');
const observer2 = new Observer('Observer 2');
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify('New data available'); // "Observer 1 received data: New data available" "Observer 2 received data: New data available"
观察者模式允许你管理状态变化并通知多个观察者,从而改善代码组织和可维护性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
43. 事件委托文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:向多个元素添加事件监听器会降低性能。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用事件委托有效地管理事件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmldocument.getElementById('parent').addEventListener('click', (event) => {
if (event.target && event.target.matches('button.className')) {
console.log('Button clicked:', event.target.textContent);
}
});
事件委托允许你通过向公共父元素添加单个事件侦听器并处理多个子元素的事件来有效地管理事件。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
44. 避免使用 `eval()`文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:使用 `eval()` 可能导致安全漏洞和性能问题。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:避免使用 `eval()` 并使用更安全的替代方案。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html// Avoid
const code = 'console.log("Hello, world!")';
eval(code); // "Hello, world!"
// Use safer alternatives
const func = new Function('console.log("Hello, world!")');
func(); // "Hello, world!"
避免使用 `eval()` 有助于防止安全漏洞和性能问题,从而使你的代码更安全、更高效。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
45. 使用 `for…of` 进行迭代文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
问题:使用 `for…in` 迭代数组容易出错。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
解决方案:使用 `for…of` 迭代数组和其他可迭代对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.htmlconst arr = [1, 2, 3, 4, 5];
for (const value of arr) {
console.log(value);
}
// 1
// 2
// 3
// 4
// 5
`for…of` 提供了一种简单而安全的方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
总结文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html
无论你是想要提升技能的经验丰富的开发人员,还是渴望学习基础知识的新手,今天内容,我想都能满足你的需求。深入了解并像专业人士一样掌握 JavaScript 的秘诀!”文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/65078.html