六个技巧让你的JavaScript代码更优雅更易维护
作为一名前端开发工程师,我们可以通过注意一些小细节,提升代码的可读性,让代码看起来更加优雅。
这次,我将分享一些易于理解、一看就懂的JavaScript技巧。
这些小贴士旨在让代码更易读、更高效。
小技巧1:减少if...else面条代码当我们发现自己在编写包含两个以上这样的if...else
语句的函数的时候,就可以考虑是否有更好的优化方法了。
function getPrice(item) {
if (item === 'apple') return 1.0;
else if (item === 'banana') return 0.5;
else if (item === 'orange') return 0.75;
// 更多情况...
}
请进入全屏模式 请退出全屏模式
这种实现方式会让函数体里塞满很多条件语句。所以,当我们想再添加一个项目时,我们就得改函数里的逻辑,再加一个 if...else
语句。
这在某种程度上会违背开闭原则(OCP)。根据OCP,当我们需要扩展功能的时候,应该通过扩展软件实体来实现需求变更,而不是修改现有的代码。
这是一个经典的优化策略。我们可以使用类似于Map
的结构来存储所有项。在这里,我们可以直接创建一个对象来存放数据。
const priceMap = {
apple: 1.0,
banana: 0.5,
orange: 0.75,
// 更多商品...
};
function getPrice(item) {
return priceMap[item] || 0; // 如果找不到商品,则返回 0
}
全屏模式 退出全屏
这种方法确保当我们需要添加一个新项目时,不必修改例如 getPrice
这样的函数的核心代码。
确实,很多人更愿意直接在需要用到的地方使用类似foodMap的东西。这里,我只是通过一个简单的例子来解释一下使用foodMap的这个想法。
const 价格表 = new Map(); // 定义一个价格表
价格表.set('apple', 1.0);
价格表.set('banana', 0.5);
价格表.set('orange', 0.75);
function 查询价格(item) { // 查询指定项目的单价
return 价格表.get(item) || 0; // 如果找不到项目,则返回0
}
切换到全屏 切换回正常模式
技巧 2:通过管道操作(pipelining operations)替换多余的循环 const foods = [
{ name: 'Apple', group: 1 },
{ name: 'Banana', group: 2 },
{ name: 'Carrot', group: 1 },
// 更多项目...
];
const group1Foods = [];
for (let i = 0; i < foods.length; i++) {
if (foods[i].group === 1) {
group1Foods.push(foods[i].name);
}
}
全屏 退出全屏
传统上,你可以使用一个 for
循环来遍历数组中的每个项目,检查每个项目的组别,然后将结果累加起来。
虽然这种方法可行,但它可能会导致代码冗长难读。通过使用 filter
和 map
这样的函数,你不仅能让代码更简洁,还能让代码更易懂。
这样一来就,很清楚这个过程首先对数组进行过滤
,然后重构
这个数组。
const group1Foods = foods
.filter(food => food.group === 1)
.map(food => food.name);
// 这段代码用于从食物列表中筛选出属于第1组的食物,并提取它们的名字
点击全屏 点击退出全屏
技巧 (Tip) 3:使用 find 替换多余的循环继续上面的例子,如果我们想要在食物对象数组中寻找特定食物,这样 find
的用处就很明显了。
例如:与其使用for循环来查找特定项,不如考虑其他方法,
const foods = [
{ name: 'Apple', group: 1 },
{ name: 'Banana', group: 2 },
{ name: 'Carrot', group: 1 },
// 更多条目...
];
let foundFood; // 找到的食品...
for (let i = 0; i < foods.length; i++) {
if (foods[i].name === 'Banana') {
foundFood = foods[i];
break;
}
}
点击进入全屏 点击退出全屏
可以直接用查找,
const foundFood = foods.find(food => food.name === 'Banana');
// 查找名为香蕉的食物
进入全屏 退出全屏
find
方法允许你快速找到数组中第一个符合测试条件的元素,提供了一个比传统循环更干净、更高效的解决方案。
当你需要检查一个数组里是否有特定值时,使用 includes
方法能大大简化你的代码。不再需要通过循环遍历来检查数组中是否包含该元素,includes
提供了一种更高效且易读的方式来实现同样的效果。
例子:
不用 for
循环来确定数组中是否包含某个元素:
const 水果 = ['Apple', 'Banana', 'Carrot'];
let 有香蕉 = false;
for (let i = 0; i < 水果.length; i++) {
if (水果[i] === 'Banana') {
有香蕉 = true;
break;
}
}
点击全屏,点击退出全屏
你可以直接用 includes
const hasBanana = fruits.includes('Banana'); // 包含香蕉
全屏模式 退出全屏
使用 includes
不仅减少了代码冗余,还让你的意图更加明确:检查数组中是否包含某个值。
这种方法提供了一个优雅的解决办法,否则将不得不使用冗长的传统循环实现。
这在处理需要频繁检查成员资格的数组时尤其有用,能帮助你写出更干净、更容易维护的代码。
方法 5:使用一致的返回值变量作为一种最佳做法,特别是在较小的功能中,最好使用例如 result
这样的变量名来表示返回值。这让大家一眼就能看出返回值的来源,并提供了一个易于识别的标准化命名规则。你和其他人可以轻松识别这种命名规则。
function calculateTotal(items) {
let result = 0;
for (let i = 0; i < items.length; i++) {
result += items[i].价格 * items[i].数量;
}
return result;
}
// 计算总价格
全屏模式,退出
技术 6:保持对象完整性在处理从后端请求返回的数据时,我们常常单独处理特定属性。这在只需处理少数几个属性时尤为常见。许多开发者倾向于只提取必要的属性来进行操作,这是第一种方法。然而,从长远来看,这种做法可能不太切实际。
当不确定一个函数将来是否需要额外的依赖模块时,保持整个对象的完整性更为明智。比如,假设 getDocDetail
函数现在使用了 icon
和 content
等属性,将来可能还会需要 title
、date
以及其他属性。传递整个对象而非单独的属性不仅缩短了参数列表,还提高了代码的可读性和灵活性。
比如说:
而不是提取和传递仅需要的属性
function getDocDetail(参数图标, 参数内容) {
// 处理参数图标和参数内容
}
const doc = { 图标: 'icon.png', 内容: 'Some content', 标题: 'Document Title', 时间: '2023-10-15' };
getDocDetail(doc.图标, doc.内容);
点击全屏 点击退出
最好是传递整个对象:
function getDocDetail(doc) {
const { icon, content } = doc;
// 处理一下 icon 和 content
// 如果以后需要用到 doc.title, doc.date 等属性
}
const doc = { icon: 'icon.png', content: 'Some content', title: '文档名称', date: '2023-10-15' };
getDocDetail(doc);
进入全屏退出全屏
这种方法让你的函数更具前瞻性,允许轻松添加任何额外属性而无需修改函数签名。随着新需求的出现,代码更健壮且易于维护,因为它避免了频繁修改函数参数的需求。这种做法符合模块化设计的原则,并有助于创建更干净且可扩展的代码库。
❤️ 最后的思考上述分享的 JavaScript 技巧可以有效提升代码质量和稳定性。通过实施这些策略,例如减少冗余循环、确保对象的完整性,并使用现代 JavaScript 方法如 filter
、map
、find
和 includes
,你能写出更干净、更高效且更易维护的代码。这样做不仅能简化你的编码过程,还符合业界的最佳实践,使你的应用程序更加健壮和灵活。
所以,试试看你在你下一个项目中应用这些建议,亲身体会这些改进,感受其中的不同。祝你编程快乐!
共同学习,写下你的评论
评论加载中...
作者其他优质文章