20 个你可能从未用过的鲜为人知的 JavaScript 功能
由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!
请访问原文链接https://devaradise.com/lesser-known-javascript-features阅读文章,以获得更佳的导航体验。
JavaScript 是现代 Web 开发的基石,为动态网站和应用程序提供强大动力。虽然许多开发者都熟悉 JavaScript 的基本和常用功能,但许多隐藏功能却常常被忽视。这些鲜为人知的功能可以使你的代码更简洁、更易读、更强大。
本文将探索一些 JavaScript 的隐藏特性。从空值合并运算符到 Map 和 Set 对象,每个特性都包含实用示例和最佳实践。利用这些特性可以帮助您编写更简洁、更高效的代码,并轻松解决复杂问题。
无论你是经验丰富的开发者还是初学者,本文都将为你介绍一些尚未充分利用的 JavaScript 功能。读完本文,你将掌握提升 JavaScript 编码技能的新技巧。
其他关于 Javascript 的文章
鲜为人知的 JavaScript 功能
1. 无效合并算子
空值合并运算符 ( ??) 用于在变量为空null或为假时提供默认值undefined。
代码示例:
let foo = null;
let bar = foo ?? 'default value';
console.log(bar); // Output: 'default value'
使用空值合并运算符来处理可能出现空值null或undefined空值的情况,确保你的代码在使用默认值时能够顺利运行。
2. 可选链式调用
可选链式运算符 ( ?.) 允许安全地访问深层嵌套的对象属性,避免因属性不存在而导致运行时错误。
代码示例:
const user = {
profile: {
name: 'Alice'
}
};
const userProfileName = user.profile?.name;
console.log(userProfileName); // Output: 'Alice'
const userAccountName = user.account?.name;
console.log(userAccountName); // Output: undefined
使用可选链可以避免在访问潜在对象null或undefined对象的属性时出错,从而使您的代码更加健壮。
3. 数字分隔符
数字分隔符(_)通过视觉上分隔数字,使大数字更易于阅读。
代码示例:
const largeNumber = 1_000_000;
console.log(largeNumber); // Output: 1000000
使用数字分隔符可以提高代码中大数字的可读性,尤其是在进行财务计算或处理大型数据集时。
4. 承诺。一切就绪
Promise.allSettled等待所有承诺得到解决(无论是已履行还是已拒绝),并返回一个描述结果的对象数组。
代码示例:
const promises = [Promise.resolve('Success'), Promise.reject('Error'), Promise.resolve('Another Success')];
Promise.allSettled(promises).then((results) => {
results.forEach((result) => console.log(result));
});
// Output:
// { status: 'fulfilled', value: 'Success' }
// { status: 'rejected', reason: 'Error' }
// { status: 'fulfilled', value: 'Another Success' }
Promise.allSettled当您需要处理多个承诺并希望确保所有结果都得到处理,而不管单个承诺的结果如何时,请使用此功能。
5. 私人班级领域
私有类字段是只能在其声明的类中访问和修改的属性。
代码示例:
class MyClass {
#privateField = 42;
getPrivateField() {
return this.#privateField;
}
}
const instance = new MyClass();
console.log(instance.getPrivateField()); // Output: 42
console.log(instance.#privateField); // Uncaught Private name #privateField is not defined.
使用私有类字段将数据封装在类中,确保敏感数据不会在类外部暴露或修改。
6. 逻辑赋值运算符
逻辑赋值运算符(&&=,,||=)??=将逻辑运算符与赋值结合起来,提供了一种根据条件更新变量的简洁方法。
代码示例:
let a = true;
let b = false;
a &&= 'Assigned if true';
b ||= 'Assigned if false';
console.log(a); // Output: 'Assigned if true'
console.log(b); // Output: 'Assigned if false'
使用逻辑赋值运算符可以简化条件赋值,使代码更易读、更简洁。
7. 循环语句和代码块语句的标签
标签是标识符,后跟冒号,用于标记循环或代码块,以便在 break 或 continue 语句中引用。
代码示例:
outerLoop: for (let i = 0; i < 3; i++) {
console.log(`Outer loop iteration ${i}`);
for (let j = 0; j < 3; j++) {
if (j === 1) {
break outerLoop; // Break out of the outer loop
}
console.log(` Inner loop iteration ${j}`);
}
}
// Output:
// Outer loop iteration 0
// Inner loop iteration 0
labelBlock: {
console.log('This will be printed');
if (true) {
break labelBlock; // Exit the block
}
console.log('This will not be printed');
}
// Output:
// This will be printed
使用标签来控制复杂的循环行为,可以更轻松地管理嵌套循环并提高代码清晰度。
8. 带标签的模板文字
带标签的模板字面量允许您使用函数解析模板字面量,从而实现对字符串字面量的自定义处理。
代码示例 1:
function logWithTimestamp(strings, ...values) {
const timestamp = new Date().toISOString();
return (
`[${timestamp}] ` +
strings.reduce((result, str, i) => {
return result + str + (values[i] || '');
})
);
}
const user = 'JohnDoe';
const action = 'logged in';
console.log(logWithTimestamp`User ${user} has ${action}.`);
// Outputs: [2024-07-10T12:34:56.789Z] User JohnDoe has logged in.
代码示例 2:
function validate(strings, ...values) {
values.forEach((value, index) => {
if (typeof value !== 'string') {
throw new Error(`Invalid input at position ${index + 1}: Expected a string`);
}
});
return strings.reduce((result, str, i) => {
return result + str + (values[i] || '');
});
}
try {
const validString = validate`Name: ${'Alice'}, Age: ${25}`;
console.log(validString); // This will throw an error
} catch (error) {
console.error(error.message); // Outputs: Invalid input at position 2: Expected a string
}
使用带标签的模板字面量进行高级字符串处理,例如创建安全的 HTML 模板或本地化字符串。
9. 位运算符在快速数学运算中的应用
JavaScript 中的位运算符对数字的二进制表示进行运算。它们通常用于底层编程任务,但对于快速的数学运算也十分方便。
位运算符列表
&(和)|(或者)^(异或)~(不是)<<(左移)>>(右移)>>>(无符号右移)
代码示例 1:
您可以使用 AND 运算符来检查一个数字是偶数还是奇数。
const isEven = (num) => (num & 1) === 0;
const isOdd = (num) => (num & 1) === 1;
console.log(isEven(4)); // Outputs: true
console.log(isOdd(5)); // Outputs: true
代码示例 2:
您可以使用左移(<<)和右移(>>)运算符分别乘以和除以 2 的幂。
const multiplyByTwo = (num) => num << 1;
const divideByTwo = (num) => num >> 1;
console.log(multiplyByTwo(5)); // Outputs: 10
console.log(divideByTwo(10)); // Outputs: 5
代码示例 3:
你可以使用 AND 运算符来检查一个数是否是 2 的幂。
const isPowerOfTwo = (num) => num > 0 && (num & (num - 1)) === 0;
console.log(isPowerOfTwo(16)); // Outputs: true
console.log(isPowerOfTwo(18)); // Outputs: false
对于需要底层二进制操作或快速数学运算的性能关键型应用,请使用位运算符。
10.in财产检查操作员
该in运算符检查对象中是否存在某个属性。
代码示例:
const obj = { name: 'Alice', age: 25 };
console.log('name' in obj); // Output: true
console.log('height' in obj); // Output: false
使用该in运算符可以验证对象中属性是否存在,确保你的代码能够优雅地处理缺少属性的对象。
11.debugger声明
该debugger语句会调用所有可用的调试功能,例如在代码中设置断点。
代码示例:
function checkValue(value) {
debugger; // Execution will pause here if a debugger is available
return value > 10;
}
checkValue(15);
在开发过程中使用该debugger语句可以暂停执行并检查代码行为,从而帮助您更高效地识别和修复错误。
12. 链式赋值
链式赋值允许你在一条语句中将同一个值赋给多个变量。
代码示例:
let a, b, c;
a = b = c = 10;
console.log(a, b, c); // Output: 10 10 10
使用链式赋值将多个变量初始化为相同的值,从而减少代码冗余。
13. 动态函数名称
动态函数名允许您定义在运行时计算名称的函数。
代码示例:
const funcName = 'dynamicFunction';
const obj = {
[funcName]() {
return 'This is a dynamic function';
}
};
console.log(obj.dynamicFunction()); // Output: 'This is a dynamic function'
使用动态函数名创建基于运行时数据的函数名称,从而增强代码的灵活性和可重用性。
14. 获取函数参数
该arguments对象是一个类似数组的对象,其中包含传递给函数的参数。
代码示例:
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sum(1, 2, 3)); // Outputs: 6
使用该arguments对象可以访问传递给函数的所有参数,这对于具有可变长度参数的函数非常有用。
15. 一元+运算符
一元运算符(+)将其操作数转换为数字。
代码示例:
console.log(+'abc'); // Outputs: NaN
console.log(+'123'); // Outputs: 123
console.log(+'45.67'); // Outputs: 45.67 (converted to a number)
console.log(+true); // Outputs: 1
console.log(+false); // Outputs: 0
console.log(+null); // Outputs: 0
console.log(+undefined); // Outputs: NaN
使用一元运算符可以快速进行类型转换,尤其是在处理用户输入或来自外部来源的数据时。
16. 指数运算**运算符
指数运算符(**)对其操作数进行指数(幂)运算。
代码示例:
const base = 2;
const exponent = 3;
const result = base ** exponent;
console.log(result); // Output: 8
在涉及幂运算的数学表达式中,例如科学或金融计算中,可以使用指数运算符,使表达式简洁易读。
17. 函数属性
JavaScript 中的函数是对象,可以拥有属性。
代码示例 1:
function myFunction() {}
myFunction.description = 'This is a function with a property';
console.log(myFunction.description); // Output: 'This is a function with a property'
代码示例 2:
function trackCount() {
if (!trackCount.count) {
trackCount.count = 0;
}
trackCount.count++;
console.log(`Function called ${trackCount.count} times.`);
}
trackCount(); // Outputs: Function called 1 times.
trackCount(); // Outputs: Function called 2 times.
trackCount(); // Outputs: Function called 3 times.
使用函数属性来存储与函数相关的元数据或配置,从而增强代码的灵活性和组织性。
18. 对象获取器和设置器
Getter 和 setter 是获取或设置对象属性值的方法。
代码示例:
const obj = {
firstName: 'John',
lastName: 'Doe',
_age: 0, // Conventionally use an underscore for the backing property
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set age(newAge) {
if (newAge >= 0 && newAge <= 120) {
this._age = newAge;
} else {
console.log('Invalid age assignment');
}
},
get age() {
return this._age;
}
};
console.log(obj.fullName); // Outputs: 'John Doe'
obj.age = 30; // Setting the age using the setter
console.log(obj.age); // Outputs: 30
obj.age = 150; // Attempting to set an invalid age
// Outputs: 'Invalid age assignment'
console.log(obj.age); // Still Outputs: 30 (previous valid value remains)
使用 getter 和 setter 来封装对象的内部状态,提供一种受控的方式来访问和修改属性。
19.!!砰砰操作员
(双重否定)运算符!!将一个值转换为其布尔等效值。
代码示例:
const value = 'abc';
const value1 = 42;
const value2 = '';
const value3 = null;
const value4 = undefined;
const value5 = 0;
console.log(!!value); // Outputs: true (truthy value)
console.log(!!value1); // Outputs: true (truthy value)
console.log(!!value2); // Outputs: false (falsy value)
console.log(!!value3); // Outputs: false (falsy value)
console.log(!!value4); // Outputs: false (falsy value)
console.log(!!value5); // Outputs: false (falsy value)
使用该!!运算符可以快速将值转换为布尔值,这在条件表达式中非常有用。
20. Map 和 Set 对象
Map并且Set是具有独特特征的集合。Map包含键值对,而Set包含唯一值。
代码示例 1:
// Creating a Map
const myMap = new Map();
// Setting key-value pairs
myMap.set('key1', 'value1');
myMap.set(1, 'value2');
myMap.set({}, 'value3');
// Getting values from a Map
console.log(myMap.get('key1')); // Outputs: 'value1'
console.log(myMap.get(1)); // Outputs: 'value2'
console.log(myMap.get({})); // Outputs: undefined (different object reference)
代码示例 2:
// Creating a Set
const mySet = new Set();
// Adding values to a Set
mySet.add('apple');
mySet.add('banana');
mySet.add('apple'); // Duplicate value, ignored in a Set
// Checking size and values
console.log(mySet.size); // Outputs: 2 (only unique values)
console.log(mySet.has('banana')); // Outputs: true
// Iterating over a Set
mySet.forEach((value) => {
console.log(value);
});
// Outputs:
// 'apple'
// 'banana'
可Map用于键类型不限的键值对集合,以及Set唯一值集合,提供高效的数据管理方式。
结论
利用这些鲜为人知的 JavaScript 特性,您可以编写更高效、更易读、更健壮的代码。立即将这些技巧融入您的项目中,提升您的 JavaScript 技能。
我们希望本指南能为您提供有价值的见解和实用示例,帮助您充分利用这些隐藏的 JavaScript 特性。不妨大胆尝试,看看它们如何融入您的编码实践中。
如果您觉得这篇文章对您有所帮助,请分享给您的开发者同行和朋友。我很想听听您对这些功能的看法和使用体验,欢迎在下方留言。
谢谢。祝你编程愉快!
文章来源:https://dev.to/syakirurahman/20-lesser-known-javascript-features-that-you-probously-never-used-5052