本系列将分两天全面回顾ES6核心特性,上篇聚焦基础语法革新,下篇深入异步编程与高级特性
一、块级作用域:let与const的诞生
1.1 var的设计缺陷与历史问题
// 经典问题:循环中的变量泄漏
for (var i = 0; i < 5; i++) {
setTimeout(() => console.log(i), 100); // 输出5次5
}
// 变量提升导致意外行为
console.log(a); // undefined(不会报错)
var a = 10;1.2 let的块级作用域实现
// 块级作用域解决方案
for (let j = 0; j < 5; j++) {
setTimeout(() => console.log(j), 100); // 0,1,2,3,4
}
// 块级作用域示例
{
let blockScoped = \"只在块内有效\";
console.log(blockScoped); // 正常输出
}
console.log(blockScoped); // ReferenceError
1.3 const的本质与实践
// 基本类型不可变
const PI = 3.14159;
PI = 3; // TypeError
// 对象类型属性可变
const user = {
name: \"Alice\",
age: 30
};
user.age = 31; // 允许
// 冻结对象实现完全不可变
const frozenUser = Object.freeze({
name: \"Bob\",
profile: { level: 5 }
});
frozenUser.name = \"Charlie\"; // 静默失败(严格模式报错)
二、箭头函数:this绑定的革命
2.1 箭头函数基本语法
// 单参数简写
const square = x => x * x;
// 多参数写法
const sum = (a, b) => a + b;
// 多行函数体
const createUser = (name, age) => ({
name,
age,
isAdult: age >= 18
});2.2 this绑定机制
class Timer {
constructor() {
this.seconds = 0;
// 传统函数写法(需要bind)
setInterval(function() {
this.seconds++; // 错误:this指向全局对象
}, 1000);
// 箭头函数解决方案
setInterval(() => {
this.seconds++; // 正确:继承外层this
}, 1000);
}
}2.3 箭头函数与普通函数对比
| 特性 | 箭头函数 | 普通函数 |
|---|---|---|
this 绑定 |
词法作用域 (定义时确定) | 动态绑定 (调用时确定) |
arguments 对象 |
不可用 | 可用 |
| 构造函数 | 不能使用 new 调用 |
可实例化对象 |
| 原型属性 | 无 prototype 属性 |
有 prototype 属性 |
yield 关键字 |
不能用作生成器函数 | 可用作生成器函数 |
三、解构赋值:
3.1 对象解构技巧
const employee = {
id: \'E1001\',
personal: {
name: \'Alice\',
address: {
city: \'New York\',
zip: \'10001\'
}
},
department: \'Engineering\'
};
// 嵌套解构 + 重命名
const {
personal: {
name: fullName,
address: { city: residence }
},
department: dept
} = employee;
console.log(fullName); // \'Alice\'
console.log(residence); // \'New York\'
console.log(dept); // \'Engineering\'
3.2 数组解构的技巧
// 基本用法
const rgb = [255, 128, 64];
const [red, green, blue] = rgb;
// 交换变量
let a = 10, b = 20;
[a, b] = [b, a]; // a=20, b=10
// 嵌套数组解构
const matrix = [[1, 2], [3, 4]];
const [[a1, a2], [b1, b2]] = matrix;
// 跳过元素
const [first, , third] = [\'a\', \'b\', \'c\']; // first=\'a\', third=\'c\'
3.3 函数参数解构实践
// 带默认值的参数解构
function connect({
host = \'localhost\',
port = 8080,
protocol = \'http\'
} = {}) {
console.log(`${protocol}://${host}:${port}`);
}
connect(); // http://localhost:8080
connect({ port: 3000 }); // http://localhost:3000
// 混合使用数组和对象解构
function parseURL(url) {
const [protocol, path] = url.split(\'://\');
const [host, ...rest] = path.split(\'/\');
return { protocol, host, path: rest.join(\'/\') };
}
四、模板字符串:字符串处理新范式
4.1 基本插值与多行文本
const user = { name: \'Bob\', age: 28 };
// 变量插值
console.log(`Hello, ${user.name}! You are ${user.age} years old.`);
// 多行文本
const htmlTemplate = `
<div class=\"profile\">
<h2>${user.name}</h2>
<p>Age: ${user.age}</p>
</div>
`;
4.2 标签模板高级应用
// 自定义模板处理器
function highlight(strings, ...values) {
let result = \'\';
strings.forEach((str, i) => {
result += str;
if (values[i]) {
result += `<mark>${values[i]}</mark>`;
}
});
return result;
}
const price = 99.95;
const quantity = 3;
const total = highlight`Total: $${price * quantity}`;
document.body.innerHTML = total;
// 输出:Total: <mark>299.85</mark>
4.3 原始字符串访问
function showRaw(strings) {
console.log(strings.raw[0]);
}
showRaw`第一行\
第二行`; // 输出:第一行\
第二行五、函数增强特性
5.1 默认参数值
// 基本用法
function createElement(tag = \'div\', content = \'\') {
return `<${tag}>${content}</${tag}>`;
}
// 表达式作为默认值
function getDefaultSize() {
return Math.floor(Math.random() * 10) + 5;
}
function createCanvas(width = getDefaultSize(), height = width * 0.75) {
return { width, height };
}
5.2 剩余参数(...rest)
// 替代arguments对象
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3, 4)); // 10
// 与普通参数组合
function join(separator, ...items) {
return items.join(separator);
}
console.log(join(\'-\', \'a\', \'b\', \'c\')); // \"a-b-c\"
5.3 参数解构与默认值结合
function drawChart({
type = \'line\',
width = 800,
height = 600,
data = []
} = {}) {
console.log(`绘制${type}图表: ${width}x${height}`);
// 图表绘制逻辑
}
drawChart({ type: \'bar\' }); // 绘制bar图表: 800x600
drawChart(); // 绘制line图表: 800x600
六、对象字面量增强
6.1 简写属性与方法
const name = \'Alice\';
const age = 30;
// 属性简写
const user = { name, age };
// 方法简写
const cart = {
items: [],
addItem(item) { // 等价于 addItem: function(item)
this.items.push(item);
},
get count() {
return this.items.length;
}
};
6.2 计算属性名
const prefix = \'user_\';
const id = 1001;
const obj = {
[prefix + id]: \'John Doe\',
[`${prefix}${id + 1}`]: \'Jane Smith\',
// 方法名计算
[\'get\' + prefix.toUpperCase()]() {
return this[prefix + id];
}
};
console.log(obj.user_1001); // \'John Doe\'
console.log(obj.getUSER_()); // \'John Doe\'
6.3 方法定义的super绑定
const parent = {
greet() {
return \"Hello from parent!\";
}
};
const child = {
__proto__: parent,
greet() {
return super.greet() + \" And from child!\";
}
};
console.log(child.greet());
// \"Hello from parent! And from child!\"
上篇总结:ES6通过
let/const、箭头函数、解构赋值等特性彻底革新了JavaScript基础语法。下篇将回顾类继承体系、Promise异步编程、模块化系统等高级特性,敬请期待!
评论