ES6 语法概述
ES6 简介
ES(ECMAScript)是一种脚本语言规范,JavaScript 是 ECMAScript 的实现。ES6 是 ECMAScript 的第 6 个版本,通常也称为 ES2015。为了兼容老旧浏览器,可以使用 Babel 转换器将 ES6 代码转为 ES5 代码。
变量声明
let
let 关键字用于声明一个作用域被限制在块级中的变量、语句或表达式。与 var 有以下不同点:
var声明的变量作用域为全局或函数级,而let作用域仅限于块级。var声明的变量会提升,而let不会。var允许重复声明,而let不允许。- 使用
let声明的变量不能用var重复声明。
// 使用 var
function varTest() {
var x = 1;
{
var x = 2; // 同样的变量
console.log(x); // 2
}
console.log(x); // 2
}
function letTest() {
let x = 1;
{
let x = 2; // 不同的变量
console.log(x); // 2
}
console.log(x); // 1
}
const
const 声明一个常量,常量的值一旦赋值后不能更改,但对象或数组的内容可以修改。
const MY_NAME = 'chen';
MY_NAME = 'jin'; // 错误:常量不能修改
const MY_OBJECT = { "key": "value" };
MY_OBJECT.key = "otherValue"; // 允许修改对象属性
const MY_ARRAY = [];
MY_ARRAY.push('A'); // 允许修改数组内容
模板字符串
模板字符串使用反引号 (`) 定义,可以嵌入 JavaScript 表达式:
const str = 'world';
console.log(`hello ${str}`); // hello world
函数默认参数
函数可以为参数设置默认值,当没有传入参数或传入 undefined 时使用默认值:
function multiply(a, b = 1) {
return a * b;
}
console.log(multiply(5, 2)); // 10
console.log(multiply(5)); // 5
console.log(multiply(5, null)); // 0
箭头函数
箭头函数使用 => 定义,简化函数书写,并且不会绑定 this:
const arr = [1, 2, 3, 4, 5];
arr.map(item => item * 2); // [2, 4, 6, 8, 10]
箭头函数具有以下特点:
- 可以省略参数的圆括号。
- 如果函数体仅有一个
return,则可以省略return和大括号。
arr.map(item => item * 2); // 简洁写法
解构赋值
解构赋值使得从对象或数组中提取值并赋给变量变得更加简便:
对象解构
const user = { name: 'chen', age: 29 };
const { name, age } = user;
console.log(`${name} : ${age}`); // chen : 29
数组解构
const arr = [1, 2];
const [a, b] = arr;
console.log(b); // 2
解构赋值也可用于函数参数:
const add = (state, { payload }) => {
return state.concat(payload);
};
对象字面量改进
ES6 允许在对象字面量中直接定义方法或进行属性赋值:
const name = 'chen';
const age = 29;
const user = { name, age }; // 等同于 { name: name, age: age }
const obj = {
add() {} // 等同于 add: function() {}
};
展开语法 (...)
展开语法可以展开数组或对象,常用于数组合并、对象合并或克隆。
数组拷贝
const arr = [1, 2, 3];
const arr2 = [...arr]; // 浅拷贝
arr2.push(4);
数组合并
const arr1 = [0, 1, 2];
const arr2 = [3, 4, 5];
const arr3 = [...arr1, ...arr2]; // 合并数组
对象合并
const obj1 = { foo: 'bar', x: 42 };
const obj2 = { foo: 'baz', y: 13 };
const mergedObj = { ...obj1, ...obj2 }; // 合并对象
剩余语法 (...)
剩余语法用于收集多个值为一个数组,通常用于函数参数:
function sum(a, b, ...rest) {
return rest.reduce((prev, current) => prev + current);
}
console.log(sum(1, 2, 3, 4)); // 9
类(Class)
ES6 引入了 class 关键字,以更接近传统面向对象编程的方式定义类:
class User {
constructor(name) {
this.name = name;
}
say() {
return this.name;
}
}
const user = new User('chen');
console.log(user.say()); // chen
类的继承
通过 extends 关键字可以实现类的继承:
class Staff extends User {
constructor(staffId, name) {
super(name);
this.staffId = staffId;
}
toString() {
return `${this.staffId} ${super.say()}`;
}
}
const staff = new Staff(123, 'Tom');
console.log(staff.toString()); // 123 Tom
Promise
Promise 用于处理异步操作,解决回调地狱的问题:
const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve('Success!'), 300);
});
promise.then(value => console.log(value)); // Success!
异步加载图片示例
function loadImageAsync(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject(new Error('Failed to load image'));
img.src = url;
});
}
loadImageAsync('http://example.com/image.png')
.then(img => console.log('Image loaded:', img))
.catch(error => console.log(error));
Generator
Generator 函数通过 yield 关键字暂停和恢复函数执行,实现协程的效果:
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
}
const gen = helloWorldGenerator();
console.log(gen.next().value); // hello
console.log(gen.next().value); // world
使用 Generator 实现异步加载
function* gen() {
const result = yield loadImageAsync('http://example.com/image.png');
console.log(result);
}
const g = gen();
const result = g.next();
result.value.then(data => g.next(data));
模块
ES6 引入了模块化,通过 import 和 export 来引入和导出模块:
// 导入模块
import { connect } from 'dva';
import * as models from '@/models';
// 导出模块
export default App;
export class App extends Component {}
ES6 模块使得 JavaScript 更适合大型应用程序的开发,通过封装和隔离变量与函数,避免了全局污染。