前言
本文将系统解析 ES6 及后续版本中最具实践价值的六大特性:块作用域、链式调用、箭头函数、模板字符串、Promise 与 Async 异步编程模型,结合具体案例分析语法细节、使用场景及常见误区,帮助开发者建立完整的现代 JavaScript 知识体系。
一、块作用域
在 ES6 之前,JavaScript 只有全局作用域和函数作用域,缺少块级作用域。这会导致变量泄漏等问题,ES6 引入了 let 和 const 来解决这个问题,提供了块级作用域。
用法
- let:用于声明变量,变量只在其所在的块级作用域内有效。
- const:用于声明常量,一旦声明必须赋值,且不能再重新赋值。常量同样具有块级作用域。
例子
// let 的使用
function testLet() {
if (true) {
let x = 10;
console.log(x); // 输出 10
}
// console.log(x); // 报错,x 在此处未定义
// const 的使用
if (true) {
const PI = 3.14;
console.log(PI); // 输出 3.14
// PI = 3.1415; // 报错,不能重新赋值
}
// console.log(PI); // 报错,PI 在此处未定义
}
testLet();
易错点
const声明的常量如果是引用类型(如对象、数组),虽然不能重新赋值,但可以修改其内部属性。
const person = { name: 'John' };
person.name = 'Jane'; // 可以修改对象的属性
// person = { name: 'Jane' }; // 报错,不能重新赋值
二、链式调用
可选链操作符 ?. 允许在访问嵌套对象属性时,避免因为中间某个属性为 null 或 undefined 而抛出错误。
用法
当访问对象的嵌套属性时,可以使用 ?. 来安全地进行链式调用。如果链中的某个属性为 null 或 undefined,表达式会立即返回 undefined,而不会抛出错误。
例子
const message = {
body: {
user: {
firstName: 'John'
}
}
};
const firstName = message?.body?.user?.firstName || 'default';
console.log(firstName); // 输出 'John'
const emptyMessage = null;
const emptyFirstName = emptyMessage?.body?.user?.firstName || 'default';
console.log(emptyFirstName); // 输出 'default'
易错点
- 可选链操作符只能用于访问属性和调用方法,不能用于计算属性名。
- 它不会阻止
null或undefined作为属性值返回。
三、箭头函数
箭头函数是 ES6 引入的一种简洁的函数定义方式,它提供了更简洁的语法,并且没有自己的 this、arguments、super 或 new.target。
用法
箭头函数的基本语法有以下几种形式:
- 当只有一个参数时,可以省略括号:
(参数) => { 函数体 }可以写成参数 => { 函数体 }。 - 当函数体只有一条语句时,可以省略花括号和
return关键字:(参数) => 表达式。
例子
// 基本形式
const add = (a, b) => {
return a + b;
};
console.log(add(1, 2)); // 输出 3
// 省略括号和花括号
const square = num => num * num;
console.log(square(5)); // 输出 25
// 没有参数时需要括号
const greet = () => 'Hello!';
console.log(greet()); // 输出 'Hello!'
易错点
- 箭头函数没有自己的
this,它的this值继承自外层函数。这可能会导致在某些情况下与传统函数的this行为不同。
const obj = {
name: 'John',
sayName: function() {
setTimeout(() => {
console.log(this.name); // 输出 'John',因为箭头函数继承了外层函数的 this
}, 100);
}
};
obj.sayName();
- 箭头函数不能使用
arguments对象。
四、模板字符串
模板字符串是 ES6 引入的一种新的字符串语法,它允许在字符串中嵌入表达式,并且可以使用多行字符串。
用法
模板字符串使用反引号() 来定义,可以使用 ${}` 来嵌入表达式。
例子
const name = 'John';
const message = `你好,我的名字是:${name}`;
console.log(message); // 输出 '你好,我的名字是:John'
// 多行字符串
const multiLine = `
这是第一行
这是第二行
`;
console.log(multiLine);
易错点
- 模板字符串中的表达式可以是任意 JavaScript 表达式,但要注意避免语法错误。
- 反引号是模板字符串的关键符号,不要与单引号或双引号混淆。
五、Promise
Promise 是 ES6 引入的一种异步编程解决方案,用于处理异步操作的结果。在之前,处理异步操作通常使用回调函数,容易导致回调地狱,Promise 可以避免这种问题。
用法
Promise 有三种状态:
- pending(待定):初始状态,操作正在进行中。
- fulfilled(已兑现):操作成功完成。可以使用
then方法来处理成功的结果。 - rejected(已拒绝):操作失败。可以使用
catch方法来处理失败的原因。
例子
function fetchData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const success = true;
if (success) {
resolve('数据获取成功');
} else {
reject('数据获取失败');
}
}, 1000);
});
}
fetchData()
.then(result => {
console.log(result); // 输出 '数据获取成功'
})
.catch(error => {
console.error(error);
});
易错点
Promise一旦状态改变,就不会再变。- 如果在
Promise中没有正确处理错误,错误会被抛出到全局,可能导致程序崩溃。
六、Async 关键字
async/await 基于 Promise,目的是将异步代码以同步的方式书写,增强代码的可读性和可维护性。
用法
async关键字用于定义一个异步函数,异步函数总是返回一个Promise。await关键字只能在async函数内部使用,它会暂停异步函数的执行,直到Promise被解决(resolved)或被拒绝(rejected),并返回Promise的结果。
例子
function getNameFetch() {
return new Promise((resolve) => {
setTimeout(() => {
resolve('John');
}, 1000);
});
}
async function getName() {
try {
let name = await getNameFetch();
console.log(name); // 输出 'John'
} catch (error) {
console.error(error);
}
}
getName();
易错点
await只能在async函数内部使用,否则会抛出语法错误。async函数中的错误需要使用try...catch块来捕获,否则错误会被包装在返回的Promise中。
1955

被折叠的 条评论
为什么被折叠?



