刚学前端的时候,我总被 "语法糖" 这个词搞懵。后来才明白,它就像给代码加了层甜蜜外衣,让复杂操作变得简单又优雅。比如:
js
// ES5写一个求和函数
var sum = function(a, b) {
return a + b;
}
// ES6用箭头函数
const sum = (a, b) => a + b;
同样的功能,ES6 写法少了 3 行代码!这就是语法糖的魅力 ------不改变功能,只优化写法。
ES6 必学的 5 大核心语法糖
1. let/const vs var
var
声明变量,总会产生各种奇怪 bug:
js
var name = '小明';
if (true) {
var name = '小红'; // 这里会覆盖外层变量
}
console.log(name); // 小红
ES6 的let
和const
完美解决了这个问题:
js
// let有块级作用域
let name = '小明';
if (true) {
let name = '小红';
}
console.log(name); // 小明
// const声明常量
const PI = 3.1415926;
PI = 3.14; // 报错!
记住 :能用const
就别用let
,减少变量被篡改的风险。
2. 箭头函数
刚学 JS 时,写回调函数总是这样:
js
// ES5写数组map
var numbers = [1, 2, 3];
var doubled = numbers.map(function(num) {
return num * 2;
});
ES6 箭头函数让代码清爽无比:
js
// ES6箭头函数
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);
注意 :箭头函数没有自己的this
,适合处理回调函数。但如果需要改变this
指向(比如对象方法),还是要用传统函数。
3. 模板字符串
最初拼接字符串时的代码写法:
js
// ES5拼接字符串
var name = '小明';
var age = 18;
var info = '我叫' + name + ',今年' + age + '岁。';
ES6 模板字符串让我彻底解放:
js
// ES6模板字符串
const name = '小明';
const age = 18;
const info = `我叫${name},今年${age}岁。`;
还支持多行字符串:
js
const poem = `床前明月光,
疑是地上霜。
举头望明月,
低头思故乡。`;
tip:${} 里可以放任何表达式,比如函数调用、运算等。
4. 解构赋值
以前从数组或对象取值时,我总是这样:
js
// ES5取数组元素
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
// ES5取对象属性
var user = { name: '小明', age: 18 };
var name = user.name;
var age = user.age;
ES6 解构赋值让代码简洁到飞起:
js
// ES6数组解构
const [a, b] = [1, 2, 3]; // a=1, b=2
// ES6对象解构
const { name, age } = user; // name='小明', age=18
高级用法:设置默认值,防止属性不存在时报错:
js
const { city = '未知' } = user;
5. 扩展运算符
合并数组或对象时的原始方案:
js
// ES5合并数组
var arr1 = [1, 2];
var arr2 = [3, 4];
var combined = arr1.concat(arr2); // [1,2,3,4]
// ES5合并对象
var obj1 = { a: 1 };
var obj2 = { b: 2 };
var merged = Object.assign({}, obj1, obj2); // {a:1, b:2}
ES6 扩展运算符让操作更简单:
js
// ES6合并数组
const arr1 = [1, 2];
const arr2 = [3, 4];
const combined = [...arr1, ...arr2]; // [1,2,3,4]
// ES6合并对象
const obj1 = { a: 1 };
const obj2 = { b: 2 };
const merged = { ...obj1, ...obj2 }; // {a:1, b:2}
超实用场景:复制数组或对象(避免引用传递):
js
const arr = [1, 2, 3];
const copy = [...arr];
const obj = { a: 1 };
const clone = { ...obj };
高级语法糖:让代码更专业
1. Class
原始的构造函数代码:
js
// ES5构造函数
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHello = function() {
console.log(`你好,我是${this.name}`);
}
ES6 的 Class 让代码更直观:
js
// ES6 Class
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHello() {
console.log(`你好,我是${this.name}`);
}
}
继承也变得超简单:
js
class Student extends Person {
constructor(name, age, grade) {
super(name, age); // 调用父类构造函数
this.grade = grade;
}
}
2. Promise
普通方式处理异步调用:
js
// ES5回调地狱
setTimeout(function() {
console.log('第一步');
setTimeout(function() {
console.log('第二步');
setTimeout(function() {
console.log('第三步');
}, 1000);
}, 1000);
}, 1000);
ES6 的 Promise 让代码更优雅:
js
// ES6 Promise
new Promise((resolve) => {
setTimeout(() => {
resolve('第一步');
}, 1000);
}).then(result => {
console.log(result);
return new Promise((resolve) => {
setTimeout(() => {
resolve('第二步');
}, 1000);
});
}).then(result => {
console.log(result);
});
终极方案:async/await(ES2017)
js
async function run() {
const step1 = await new Promise(resolve => setTimeout(() => resolve('第一步'), 1000));
console.log(step1);
const step2 = await new Promise(resolve => setTimeout(() => resolve('第二步'), 1000));
console.log(step2);
}
run();
3. Symbol
给对象添加属性时,总担心属性名冲突:
js
// ES5属性名冲突
var obj = {
id: 1,
id: 2 // 后面的会覆盖前面的
};
ES6 的 Symbol 保证属性名唯一:
js
// ES6 Symbol
const id = Symbol('id');
const obj = {
[id]: 1,
[Symbol('id')]: 2 // 两个不同的Symbol
};
用途:定义对象的私有属性,防止外部修改。
4. Set/Map:更强大的数据结构
Set
js
// ES6 Set去重
const arr = [1, 2, 2, 3, 3, 3];
const unique = [...new Set(arr)]; // [1,2,3]
Map
js
// ES6 Map
const map = new Map();
map.set('name', '小明');
map.set('age', 18);
console.log(map.get('name')); // 小明
对比对象:Map 的键可以是任意类型,且有序存储,适合频繁增删的场景。
总结
刚学 JS 时最头疼的就是代码又长又乱!ES6 语法糖简直像随身携带的瑞士军刀 ------ 随手一掏就能砍掉 50% 冗余代码,复杂逻辑瞬间变得一目了然,写代码就像开了倍速,开发效率直接起飞!当然,学习过程中难免遇到其他困惑,像this,原型链这样的问题,可以参考我的其他文章。
互动环节:你在学习 ES6 语法糖时遇到过哪些有趣的问题?欢迎在评论区分享你的经验和困惑,大家一起讨论成长!