语法糖(Syntactic Sugar)是由英国计算机学家 Peter J. Landin 提出的一个术语,指的是在编程语言中添加的某种语法,这种语法对语言的功能没有实质性影响,但能让代码更简洁、易读,提高开发效率。语法糖的本质是对已有语言结构的简化或包装。它不会增加新的功能,而是通过更直观的语法形式来替代复杂的底层实现。
语法糖不全是优点,恰恰相反的是缺点可能比有点更多,但只针对特殊情况。
某些语法糖可能会在底层自动进行类型转换,而开发者可能并不清楚这些转换的细节。在深层嵌套的代码中过度使用语法糖,可能会使代码的可读性下降。
1. 箭头函数 (Arrow Functions)
// 传统函数
function add(a, b) { return a + b; }
// 箭头函数简写
const add = (a, b) => a + b;
备注:箭头函数虽然简洁,但它不会创建自己的 this 上下文,而是绑定词法作用域内的 this ,这可能会在某些情况下导致意外的行为
箭头函数在高频调用时可能不如传统函数高效,而模板字符串在处理非常复杂的表达式时也可能不如传统的字符串拼接
2. 解构赋值 (Destructuring)
// 数组解构
const [x, y] = [1, 2];
// 对象解构
const { name, age } = { name: 'Alice', age: 30 };
// 函数参数解构
function greet({ name }) {
return `Hello, ${name}!`;
}
3. 模板字符串 (Template Literals)
const name = 'Bob';
console.log(`Hello, ${name}!`); // 自动替换变量
4. 对象属性简写
const name = 'Charlie';
const age = 25;
// 传统写法
const obj = { name: name, age: age };
// 简写
const obj = { name, age };
5. 方法简写 (Method Shorthand)
// 传统写法
const obj = {
sayHello: function() { /*...*/ }
};
// 简写
const obj = {
sayHello() { /*...*/ }
};
6. 默认参数 (Default Parameters)
// 传统写法
function multiply(a, b) {
b = b || 1;
return a * b;
}
// 简写
function multiply(a, b = 1) {
return a * b;
}
7. 展开运算符 (Spread Operator)
// 数组合并
const arr = [...[1,2], ...[3,4]];
// 对象合并
const merged = { ...obj1, ...obj2 };
8. 剩余参数 (Rest Parameters)
function sum(...numbers) {
return numbers.reduce((a, b) => a + b);
}
9. 可选链操作符 (Optional Chaining)
// 传统写法
const street = user && user.address && user.address.street;
// 简写
const street = user?.address?.street;
10. 空值合并运算符 (Nullish Coalescing)
// 传统写法
const value = input !== null && input !== undefined ? input : 'default';
// 简写
const value = input ?? 'default';
11. 逻辑赋值运算符 (Logical Assignment)
// 传统写法
a = a || b;
a = a && b;
a = a ?? b;
// 简写
a ||= b;
a &&= b;
a ??= b;
12. 类语法糖 (Class Syntax)
// 构造函数原型写法
function Person(name) {
this.name = name;
}
Person.prototype.sayHello = function() { /*...*/ };
// 类语法糖
class Person {
constructor(name) {
this.name = name;
}
sayHello() { /*...*/ }
}
备注:class虽然让面向对象编程更直观,但类声明不会被提升,并且存在临时性死区(TDZ),这可能导致一些意外的错。
13. 动态属性名
const prop = 'age';
const obj = {
[prop]: 30 // 等同于 age: 30
};
14. 数组 includes 方法
// 传统判断是否存在
arr.indexOf('item') !== -1;
// 简写
arr.includes('item');
15. 指数运算符
// 传统写法
Math.pow(2, 3); // 8
// 简写
2 ** 3; // 8
16. 异步语法糖 (async/await)
// Promise 链
fetchData()
.then(res => process(res))
.catch(err => handleError(err));
// async/await 简写
async function handleData() {
try {
const res = await fetchData();
process(res);
} catch (err) {
handleError(err);
}
}
17. 私有类字段
class Counter {
#count = 0; // 私有字段
increment() {
this.#count++;
}
}
18. 顶层 await
// 模块中直接使用
const data = await fetchData();
19. 数字分隔符
const billion = 1_000_000_000; // 更易读
20. 标签函数 (Tagged Templates)
function highlight(strings, ...values) {
// 自定义模板处理逻辑
}
const name = 'Alice';
highlight`Hello ${name}!`;
梦泽Hexo文章模板