JavaScript 是一种应用场景多且功能强大的语言,对于现代 Web 开发至关重要。掌握一些 JavaScript 实用技巧对于提升代码质量和开发效率至关重要,这些技巧可以帮助开发者更高效地编写和维护代码,让代码变得优雅且不过时,让你成为更高效、更有效的前端开发人员。
这篇文章就来和大家一起探讨几种 JavaScript 开发技巧,每种技巧都有介绍代码和示例,让我们一起来提升你的 JavaScript 技能,做一个优雅的前端人
01、空值合并操作符??
在 JavaScript 中,两个问号 "??" 是一个称为 "Nullish Coalescing Operator"(空值合并运算符)的特殊运算符。它用于处理变量为 null 或 undefined 时的情况,只有当操作符左侧表达式的值为 undefined 或者 null 时,才会返回右侧的值。
学会"??"之前的代码:
if(name === null || name === undefined) {
doSomething()
}
学会"??"之后的代码:
name ?? doSomething();
例如:
const a = null ?? 100; // 100
const b = undefined ?? 100; // 100
const c = 0 ?? 100; // 0
const d = "" ?? 100; // ""
const e = true ?? 100; // true
const f = false ?? 100; // false
通过上面的比较可以发现,?? 操作符的出现,是为了更准确的做空值判断,只有 null 和 undefined 才会被判定为空值。虽然,数值0、空数字NaN、布尔 false、空字符串""也是假值,但不会被判定为空值。
02、使用!!操作符
在 JavaScript 中,!! 是一个常用的双重否定操作符,它的主要作用是将一个值转换为布尔值 (true 或 false)。
当你对一个值使用 ! 操作符时,它会尝试将该值转换为布尔值,并返回该布尔值的反值。例如:
!0 会返回 true,因为 0 在布尔上下文中被转换为 false。
!"123" 会返回 false,因为非空字符串在布尔上下文中被转换为 true。
当你再次使用 ! 操作符时(即 !!),你就得到了原始值的布尔表示。例如:
!!0 会返回 false,因为 !0 是 true,而 !true 是 false。
!!"123" 会返回 true,因为 !"123" 是 false,而 !false 是 true。
这种 !! 技巧经常用于确保一个值被明确地转换为一个布尔值,特别是在你需要一个布尔值但可能得到一个可以隐式转换为布尔值的其他类型(如数字、字符串或对象)的情况下。
function isTruthy(value) {
return !!value;
}
console.log(isTruthy(0)); // false
console.log(isTruthy("")); // false
console.log(isTruthy(null)); // false
console.log(isTruthy(undefined)); // false
console.log(isTruthy(NaN)); // false
console.log(isTruthy(1)); // true
console.log(isTruthy("hello")); // true
console.log(isTruthy({})); // true
console.log(isTruthy([])); // true
03、检查对象是否为空
如果想要判断某个对象是否为空,可以使用如下方式:
const a = Object.keys({}).length; // 0
const b = Object.keys({name: '前端技术营', age: 18}).length; // 2
Object.keys() 方法用于获取对象的key,会返回一个包含这些key值的数组。如果返回的数组length为0,该对象就是为空。
04、简化判断
没学习该技巧之前的代码:
if(a === undefined || a === null || a === 1 || a === 2) {
doSomething();
}
学习该技巧之后的代码:
const condition = [undefined, null, 1, 2];
if(condition.includes(a)) {
doSomething()
}
把多个值放在一个数组中,然后调用数组的 includes 方法。
这样代码就会简洁很多,并且便于扩展,如果还有需要判断的a值,直接在condition数组中添加即可。
05、初始化数组
如果想要初始化一个指定长度的数组,并指定默认值,可使用如下方式:
const arr1 = Array(6).fill('');
// ['', '', '', '', '', '']
const arr2 = Array(6).fill(1);
// [1, 1, 1, 1, 1, 1]
const arr3 = Array(4).fill({
name: '前端技术营',
age: 18
});
// [
// {name: '前端技术营', age: 18},
// {name: '前端技术营', age: 18},
// {name: '前端技术营', age: 18},
// {name: '前端技术营', age: 18}
// ]
06、给多个变量赋值
当我们想给多个不同的变量赋值时,这种技巧非常有用。
没学习该技巧之前的代码:
let x, y, z;
x = 1;
y = 2;
z = 3;
学习该技巧之后的代码:
let [x, y, z] = [1, 2, 3];
07、函数只执行一次
在有些特殊的场景中,某一个函数只允许执行一次,或者绑定的某一个方法只允许执行一次,可以利用闭包来判断改函数是否执行过。
export function implementOnce(fn) {
// 利用闭包判断函数是否执行过
let called = false;
return function() {
if(!called) {
called = true;
fn.apply(this, arguments);
}
}
}
08、可选链
可选链运算符(?.)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。在引用为空(null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。
当尝试访问可能不存在的对象属性时,可选链运算符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链运算符也是很有帮助的。
没学习该技巧之前的代码:
const user = {
employee: {
programmer: {
name: 'xxx'
}
}
};
console.log(user.employee.coder.name);
// Uncaught TypeError: Cannot read properties of undefined (reading 'name')
// 或者用作判断
if (
user &&
user.employee &&
user.employee.programmer &&
user.employee.programmer.name
) {
doSomething();
}
学习该技巧之后的代码:
const user = {
employee: {
programmer: {
name: 'xxx'
}
}
};
console.log(user.employee?.programmer?.name); // xxx
console.log(user.employee?.coder?.name); // undefined
// 或者用作判断
if(user.employee?.coder?.name) {
doSomething();
}
09、动态属性名称
可以使用方括号将变量用作对象属性名称,使用方式如下:
const key = 'name';
const person = { [key]: 'xxx' };
console.log(person.name); // xxx
10、使用结构交换值
可以使用解构轻松地交换两或多个变量。
let x = 10, y = 20, z = 30;
[x, y, z] = [z, x, y];
console.log(x); //30
console.log(y); //10
console.log(z); //20
11、数字范围比较
有时候可能需要将数字限制在特定范围内。每次需要时都用三元运算符来做是一件很不优雅的事情,使用函数则要优雅得多。
const constrain = (num, min, max) => {
if(num < min) return min;
else if(num > max) return max;
else return num;
}
constrain(5, 1, 3) // 3
constrain(2, 1, 5) // 2
constrain(0, -100, 100) // 0
更优雅的方法:
const constrain = (num, min, max) => Math.min(Math.max(num, min), max)
12、使用Map数据结构
使用Map数据结构来管理数据是一种常见的编程技巧,可以提高代码的可读性和可维护性。
Map是ES6中新增的一种数据结构,可以用来存储键值对。相比于传统的对象,Map的优势在于可以使用任意类型作为键名,键值对的顺序不会改变,并且可以快速获取大小信息。
在前端开发中,可以使用Map来管理数据,如页面中的列表、表单等。通过使用Map,可以将数据按照键值对的形式存储,可以提高代码的可读性和可维护性。例如,在一个页面中,需要管理多个表单元素的值,可以使用Map来存储这些值。这样,每个表单元素的值都可以通过对应的键名来获取,代码可读性更高,而且方便修改和维护。
// 创建一个Map对象
const formMap = new Map();
// 添加表单元素的值到Map中
formMap.set('username', 'xxx');
formMap.set('password', '123456');
// 获取表单元素的值
const username = formMap.get('username');
const password = formMap.get('password');
同时,Map也提供了一些方便的方法,如set()、get()、has()、delete()等,可以方便地对数据进行操作。
当页面中存在一个列表需要管理时,可以使用Map来存储列表数据。
const listMap = new Map();
listMap.set(1, { id: 1, name: '小明' });
listMap.set(2, { id: 2, name: '小华' });
可以使用get()方法来获取对应项的值:
const currentItem = listMap.get(1);
总结
JavaScript 最初是为了给网站添加一些功能而被设计出来的简单语言。但是时至今日,它无处不在,而且还更加复杂了。随着 Web 应用程序越来越复杂,JavaScript 也发展得越来越快。编写简洁、可读且可维护的 JavaScript 程序不再像以前那么容易了。这些技巧可以帮助您更高效地编写和维护代码,助力高效开发。
如果你觉得这些技巧很棒的话,请记得点赞我,关注我,并将这篇文章分享给你的朋友们,也许能够帮助到他。
推荐阅读
2、厉害了!这是JavaScript中的数据类型判断方法最全总结
3、详解JavaScript异步编程之async和await
5、一个reduce还能玩出这么多花样儿?中高级前端都知道的reduce函数高级用法
求分享
求收藏
求点击
求在看