一、ES6简介与核心定位
1.1 什么是ES6?
ECMAScript 6.0(简称ES6)是JavaScript语言的下一代标准,于2015年6月正式发布。从ES6开始,ECMAScript采用"年号版本"命名,即ES6等价于ECMAScript 2015,后续每年更新一个版本(如ES7=2016、ES8=2017等)。
ES6的核心目标的是升级JavaScript语言能力,解决原有语法的繁琐、功能不足等问题,让JS能编写复杂大型应用程序,跻身企业级开发语言行列。
1.2 ECMAScript与JavaScript的关系
很多人会混淆两者,其实核心是"规范 "与"实现 "的关系,结合前端发展历程更易理解:
Web发展与JS标准化历程
- Web1.0时代:网页以静态HTML为主,仅关注样式和内容,无复杂交互需求。
- Web2.0时代 :交互需求激增,JS应运而生并走向标准化:
- 1995年:网景工程师Brendan Eich仅用10天设计出JavaScript。
- 1996年:微软发布JScript(JS的逆向实现),浏览器兼容性问题凸显。
- 1996年11月:网景公司将JS提交给ECMA国际(欧洲计算机制造商协会),寻求标准化。
- 1997年:ECMA发布ECMA-262标准,定义浏览器脚本语言规范,命名为ECMAScript(1.0版)。
核心结论:ECMAScript是脚本语言的官方规范,规定语法、特性、API;JavaScript、JScript是该规范的具体实现,各大浏览器厂商按ECMAScript标准实现JS引擎,保障语言一致性。
二、ES6高频新特性(实战重点)
2.1 变量声明升级:let与const
ES5中仅用var声明变量,存在作用域混乱、变量提升、可重复声明等问题,ES6新增let(块级变量)和const(常量)解决这些痛点。
let声明变量(推荐优先使用)
bash
// 1. 块级作用域(仅在{}内有效,解决var越域问题)
{
var a = 1; // var无块级作用域,全局可访问
let b = 2; // let有块级作用域,{}外不可访问
}
console.log(a); // 输出1(正常访问)
console.log(b); // ReferenceError: b is not defined(报错,无法访问块内let变量)
// 2. 不可重复声明(避免变量覆盖)
var m = 1;
var m = 2; // var可重复声明,后值覆盖前值
let n = 3;
// let n = 4; // 报错:Identifier 'n' has already been declared
// 3. 无变量提升(避免"先使用后声明"的逻辑混乱)
console.log(x); // undefined(var存在变量提升,声明提前但值为undefined)
var x = 10;
console.log(y); // ReferenceError: y is not defined(let无提升,必须先声明后使用)
let y = 20;
const声明常量(只读变量)
bash
// 1. 声明后不可修改(基本类型值固定)
const a = 1;
a = 3; // Uncaught TypeError: Assignment to constant variable.(报错,无法修改)
// 2. 必须初始化(声明时必须赋值,否则报错)
// const b; // 报错:Missing initializer in const declaration
// 🌟 避坑:const声明引用类型(对象/数组),仅地址不可改,内容可改
const person = { name: "jack" };
person.name = "rose"; // 正常执行(修改对象内容,地址未变)
// person = {}; // 报错(修改对象地址,违反const规则)
使用建议:优先用const(值不变时),值可能变化时用let,彻底替代var,避免作用域相关bug。
2.2 解构表达式:简化变量赋值
针对数组 、对象 ,ES6提供解构语法,可快速提取其中的值赋值给变量 ,替代传统"角标/点语法",简洁高效。
数组解构
bash
let arr = [1, 2, 3];
// ES5写法:通过角标取值,繁琐
let x = arr[0];
let y = arr[1];
let z = arr[2];
// ES6解构写法:按位置一一对应赋值
const [x1, y1, z1] = arr;
console.log(x1, y1, z1); // 输出1 2 3
// 拓展:跳过元素、设置默认值
const [a, , b] = arr; // 跳过第二个元素,a=1,b=3
const [c, d, e = 4] = [1, 2]; // e无对应值,取默认值4
对象解构(开发高频)
bash
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
};
// ES5写法:逐个提取,重复代码多
const name = person.name;
const age = person.age;
const language = person.language;
// ES6解构写法:按属性名匹配赋值
const { name: nn, age, language } = person;
// 说明:name: nn 表示将person.name赋值给变量nn(重命名,避免变量名冲突)
console.log(nn); // 输出jack
console.log(age); // 输出21
console.log(language); // 输出['java', 'js', 'css']
// 拓展:嵌套对象解构
const user = { info: { id: 1001, addr: "北京" } };
const { info: { id, addr } } = user;
console.log(id, addr); // 输出1001 北京
2.3 字符串扩展:增强API与模板字符串
新增字符串API(实用判断功能)
includes(str):返回布尔值,表示是否找到了参数字符串。startsWith(str):返回布尔值,表示参数字符串是否在原字符串的头部。endsWith(str):返回布尔值,表示参数字符串是否在原字符串的尾部。repeat(n): 返回一个新字符串,表示将原字符串重复n次。padStart(int maxLen, int str):前补充,第一个参数是字符串补全生效的最大长度,第二个参数是用来补全的字符串。padEnd(int maxLen, int str):后补充trimStart():消除字符串头部的空格,返回新字符串,不会修改原始字符串trimEnd():消除尾部的空格matchAll():返回一个正则表达式在当前字符串的所有匹配replaceAll(searchValue, replacement):一次性替换所有匹配。- 第二个参数replacement是一个字符串,表示替换的文本,其中可以使用一些特殊字符串。
$&:匹配的字符串。- `$ :匹配结果前面的文本。
- $':匹配结果后面的文本。
- $n:匹配成功的第n组内容,n是从1开始的自然数。这个参数生效的前提是,第一个参数必须是正则表达式。
-
:指代美元符号:指代美元符号:指代美元符号。
- 第二个参数replacement是一个字符串,表示替换的文本,其中可以使用一些特殊字符串。
bash
let str = "hello.vue";
// includes(子串):判断是否包含子串,返回布尔值
console.log(str.includes("e")); // true
console.log(str.includes("hello")); // true
// startsWith(子串):判断是否以子串开头
console.log(str.startsWith("hello")); // true
// endsWith(子串):判断是否以子串结尾
console.log(str.endsWith(".vue")); // true
console.log(str.endsWith("vue")); // true(无需包含小数点,精准匹配)
'x'.repeat(3) // "xxx"
'hello'.repeat(2) // "hellohello"
'na'.repeat(0) // ""
//es2017引入
'x'.padStart(5, 'ab') // 'ababx'
'x'.padStart(4, 'ab') // 'abax'
'x'.padEnd(5, 'ab') // 'xabab'
'x'.padEnd(4, 'ab') // 'xaba'
//es2019引入
const s = ' abc ';
s.trim() // "abc"
s.trimStart() // "abc "
s.trimEnd() // " abc"
'aabbcc'.replaceAll('b', '_')
// $& 表示匹配的字符串,即`b`本身
// 所以返回结果与原字符串一致
'abbc'.replaceAll('b', '$&') // 'abbc'
// $` 表示匹配结果之前的字符串
// 对于第一个`b`,$` 指代`a`
// 对于第二个`b`,$` 指代`ab`
'abbc'.replaceAll('b', '$`') // 'aaabc'
// $' 表示匹配结果之后的字符串
// 对于第一个`b`,$' 指代`bc`
// 对于第二个`b`,$' 指代`c`
'abbc'.replaceAll('b', `$'`) // 'abccc'
// $1 表示正则表达式的第一个组匹配,指代`ab`
// $2 表示正则表达式的第二个组匹配,指代`bc`
'abbc'.replaceAll(/(ab)(bc)/g, '$2$1') // 'bcab'
// $$ 指代 $
'abc'.replaceAll('b', '$$') // 'a$c'
//第二个参数 也可以是一个函数
'aabbcc'.replaceAll('b', () => '_')
const str = 'hello';
str.at(1) // "e"
str.at(-1) // "o"
模板字符串(语法糖神器)
用反引号`````包裹,解决传统字符串多行、插变量繁琐的问题,支持多行文本、变量嵌入、函数调用。
bash
// 1. 多行字符串(无需拼接\n,保留格式)
let html = `
<div>
<span>hello world</span>
</div>
`;
console.log(html); // 按格式输出多行HTML片段
// 2. 嵌入变量/表达式(${}内可放JS变量、运算、逻辑)
let name = "张三";
let age = 18;
let info = `我是${name},今年${age}岁,明年${age + 1}岁`;
console.log(info); // 输出:我是张三,今年18岁,明年19岁
// 3. 嵌入函数调用(${}内可执行函数,取返回值)
function getSkill() {
return "JavaScript";
}
let intro = `我擅长${getSkill()}开发`;
console.log(intro); // 输出:我擅长JavaScript开发
2.4 函数优化:简化写法与增强功能
参数默认值(避免手动判断默认值)
bash
// ES5写法:需手动判断参数是否为空,繁琐且有坑
function add(a, b) {
b = b || 1; // 坑:若b传0,会被当作false取默认值1
return a + b;
}
console.log(add(10)); // 11
// ES6写法:直接给参数设默认值,简洁无坑
function add2(a, b = 1) {
return a + b;
}
console.log(add2(10)); // 11(b未传,取默认值1)
console.log(add2(10, 0)); // 10(b传0,正常使用,无坑)
不定参数(处理不确定个数的参数)
用...变量名表示,接收所有剩余参数,组成数组,替代ES5的arguments,语法更清晰。
bash
// 不定参数需放在参数列表最后,且仅能有一个
function sum(...values) {
// values是数组,可使用数组方法
return values.reduce((a, b) => a + b, 0);
}
console.log(sum(1, 2)); // 3(values = [1,2])
console.log(sum(1, 2, 3, 4)); // 10(values = [1,2,3,4])
// 结合固定参数使用
function fun(name, ...hobbies) {
console.log(`${name}的爱好:${hobbies.join(",")}`);
}
fun("jack", "coding", "reading"); // 输出:jack的爱好:coding,reading
箭头函数(简写+this优化)
ES6定义函数的简写方式,核心优势:语法简洁、解决this指向混乱问题(箭头函数无自身this,指向外层作用域this)。
bash
// 1. 单个参数:省略括号
// ES5写法
var print = function (obj) {
console.log(obj);
};
// 箭头函数简写
var print2 = obj => console.log(obj);
print2(100); // 输出100
// 2. 多个参数:括号不可省略;单行返回:省略{}和return
// ES5写法
var sum = function (a, b) {
return a + b;
};
// 箭头函数简写
var sum2 = (a, b) => a + b;
console.log(sum2(10, 20)); // 30
// 3. 多行代码:需用{}包裹,手动return
var sum3 = (a, b) => {
let c = a + b;
return c; // 多行必须手动return
};
// 🌟 核心优势:this指向固定(无自身this)
const person = {
name: "jack",
// 普通函数:this指向调用者(person对象)
say1: function () {
console.log(this.name);
},
// 箭头函数:this指向外层作用域(全局window)
say2: () => {
console.log(this.name); // 输出undefined(window无name属性)
}
};
person.say1(); // jack
person.say2(); // undefined
实战:箭头函数+解构表达式
bash
// 需求:提取对象属性作为函数参数
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
};
// ES5写法:需手动提取属性
function hello(person) {
console.log("hello," + person.name);
}
// ES6写法:箭头函数+对象解构,简洁高效
const hello2 = ({ name }) => console.log("hello," + name);
hello2(person); // 输出hello,jack
2.5 对象优化:语法糖与API增强
新增Object API(实用工具方法)
Object.keys():返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。Object.values():返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。Object.entries():返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。Object.assign(target,src,..):用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。第一个参数是目标对象,后面的参数都是源对象。
bash
const person = {
name: "jack",
age: 21,
language: ['java', 'js', 'css']
};
// 1. Object.keys(obj):获取所有key组成的数组
console.log(Object.keys(person)); // ["name", "age", "language"]
// 2. Object.values(obj):获取所有value组成的数组
console.log(Object.values(person)); // ["jack", 21, ["java", "js", "css"]]
// 3. Object.entries(obj):获取[key, value]二维数组
console.log(Object.entries(person)); // [["name","jack"], ["age",21], ["language",[...]]]
// 4. Object.assign(dest, ...src):合并对象(浅拷贝)
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };
Object.assign(target, source1, source2);
console.log(target); // {a: 1, b: 2, c: 3}(target被修改)
// 注意:第一层深拷贝,第二层浅拷贝(引用类型仅复制地址)
对象简写语法(开发高频)
bash
// 1. 属性简写:属性名与变量名一致时,可省略属性值
const age = 23;
const name = "张三";
// ES5写法
const person1 = { age: age, name: name };
// ES6简写
const person2 = { age, name };
console.log(person2); // {age: 23, name: "张三"}
// 2. 函数属性简写:省略function关键字
const person3 = {
name: "jack",
// ES5写法
eat: function (food) {
console.log(this.name + "在吃" + food);
},
// ES6简写
eat2(food) {
console.log(this.name + "在吃" + food);
}
};
person3.eat2("apple"); // 输出jack在吃apple
对象拓展运算符(...)
用于拷贝对象、合并对象,语法简洁,替代Object.assign的部分场景。
bash
// 1. 拷贝对象(浅拷贝,同Object.assign)
let person1 = { name: "Amy", age: 15 };
let someone = { ...person1 };
console.log(someone); // {name: "Amy", age: 15}(新对象,修改不影响原对象)
// 2. 合并对象(后面对象覆盖前面对象同名属性)
let obj1 = { a: 1, b: 2 };
let obj2 = { b: 3, c: 4 };
let obj3 = { ...obj1, ...obj2 };
console.log(obj3); // {a: 1, b: 3, c: 4}(obj2的b覆盖obj1的b)
2.6 数组新方法:map与reduce(实战核心)
map:数组映射(批量处理元素)
接收一个处理函数,遍历原数组,将每个元素用函数处理后,返回新数组(不修改原数组)。
bash
// 案例1:字符串数组转数字数组
let arr = ['1', '20', '-5', '3'];
let numArr = arr.map(s => parseInt(s));
console.log(numArr); // [1, 20, -5, 3]
// 案例2:批量格式化数据
let users = [{ name: "jack", age: 21 }, { name: "rose", age: 19 }];
let userNames = users.map(user => user.name);
console.log(userNames); // ["jack", "rose"]
reduce:数组累加/汇总(灵活高效)
遍历数组,依次执行回调函数,将数组元素"汇总"为一个值(如求和、求最大值、累加对象属性等)。
bash
// 语法:arr.reduce(回调函数, 初始值)
// 回调函数参数:prev(上一次结果)、curr(当前元素)、index(索引)、arr(原数组)
const arr = [1, 20, -5, 3];
// 案例1:求和(无初始值,prev默认取第一个元素)
let total = arr.reduce((prev, curr) => prev + curr);
console.log(total); // 19(1+20-5+3)
// 案例2:求和(有初始值,推荐!避免数组为空报错)
let total2 = arr.reduce((prev, curr) => prev + curr, 1);
console.log(total2); // 20(1+1+20-5+3)
// 案例3:求数组最大值
let max = arr.reduce((prev, curr) => prev > curr ? prev : curr);
console.log(max); // 20
// 案例4:累加对象属性
let goods = [{ price: 10, count: 2 }, { price: 20, count: 3 }];
let totalPrice = goods.reduce((prev, curr) => prev + curr.price * curr.count, 0);
console.log(totalPrice); // 80(10*2 + 20*3)
三、ES6与ES5核心差异对比(互补重点)
| 功能场景 | ES5写法 | ES6写法 | 优化点 |
|---|---|---|---|
| 变量声明 | var a = 1; | let a = 1; const b = 2; | 块级作用域,无提升,不可重复声明 |
| 对象取值 | var name = person.name; | const { name } = person; | 简化赋值,减少重复代码 |
| 函数定义 | function(a,b){return a+b;} | (a,b) => a+b | 语法简洁,this指向固定 |
| 数组处理 | 循环遍历处理元素 | arr.map(...).reduce(...) | 无循环化,代码更优雅 |
| 字符串拼接 | "我是" + name + ",今年" + age; | 我是${name},今年${age}; |
支持多行,嵌入变量/函数 |
四、学习小结
- ES6的核心价值是语法简化 和功能增强,解决ES5的繁琐语法、逻辑漏洞,提升开发效率和代码可维护性。
- 高频重点:let/const(变量规范)、解构表达式(赋值简化)、箭头函数(this优化)、map/reduce(数组处理)、对象简写(代码精简)。
- 避坑提醒:箭头函数不适合作为对象方法(this指向问题)、const声明引用类型仅地址不可改、reduce建议加初始值避免空数组报错。
- 学习建议:ES6是现代JS开发的基础,结合框架(Vue/React)实战强化,逐步用ES6替代ES5写法,形成规范编码习惯。