ES6 新特性
ECMAScript
是由Ecma国际通过ECMA-262标准化的脚本程序设计语言。ES6 入门教程
let
关键字
let
关键字用来声明变量,使用let
声明的变量有几个特点:
- 不允许重复声明
- 块级作用域
- 不存在变量提升
- 不影响作用域链
const
关键字
const
关键字用来声明常量,const
声明有以下特点:
- 声明必须要赋初始值
- 常量的名称一般大写
- 不能修改常量的值
- 不允许重复声明
- 块级作用域
var和let的区别?
- var声明的变量没有块作用域,let声明的有块作用域
- var可以声明同一个变量(覆盖),let不可以
- var有变量提升,let没有
对象属性修改和数组元素变化不会触发 const
错误
应用场景:声明对象类型使用 const
,非对象类型声明选择 let
变量的解构赋值
ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
// 表示,可以从数组中提取值,按照对应位置,对变量赋值。
let [a, b, c] = [10, 20, 30];
const arr = ['宋小宝', '刘能', '赵四', '小沈阳'];
let [song, liu, zhao, xiao] = arr;
console.log(song, liu, zhao, xiao);
let {a, b} = {a: 10, b: 20};
const star = {
name: '于谦',
tags: ['抽烟', '喝酒', '烫头'],
say: function () {
console.log('我可以说相声');
}
};
let {name, tags: [chou, he, tang], say} = star;
let obj = {a: 1, b: {c: 2}};
//标准的解构赋值
// const {c} = obj.b;
//连续解构赋值
const {b: {c}} = obj;
//连续解构赋值 + 重命名
const {b: {c: value}} = obj;
const [a, b, c, d, e] = 'hello';
a // "h"
b // "e"
c // "l"
d // "l"
e // "o"
频繁使用对象方法、数组元素,就可以使用解构赋值形式。
模板字符串
模板字符串(template string) 是增强版的字符串,用反引号(`)标识,特点:
- 字符串中可以出现换行符
- 可以使用
${xxx}
形式输出变量
//直接使用换行符
let str = `<ul>
<li>沈腾</li>
<li>玛丽</li>
<li>艾伦</li>
<li>魏翔</li>
</ul>`;
//字符串中进行变量拼接
let star = '魏翔';
let str2 = `我特别喜欢${star}`;
注意:当遇到字符串与变量拼接的情况使用模板字符串
简化对象写法
ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
let name = 'Tom';
let pos = '北京';
let change = function () {
console.log('改变');
};
const i = {
name,
pos,
change,
improve() {
console.log('提升');
}
}
箭头函数
ES6 允许使用「箭头」(=>)定义函数。
//1. 声明格式
let add = (a, b, c) => {
return a + b + c;
};
//2. 函数调用
console.log(add(1, 2, 3));
console.log(add.call({}, 1, 2, 3));
console.log(add.apply({}, [1, 2, 3]));
箭头函数的注意点:
- 如果形参只有一个,则小括号可以省略
- 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果(如果不写花括号的话,
return
也不能写) - 箭头函数
this
指向声明时所在作用域下this
的值 - 箭头函数不能作为构造函数实例化
- 箭头函数不能使用
arguments
注意:箭头函数不会更改this指向,所以非常适合设置与this无关的回调,比如数组回调、定时器回调,不适合事件回调与对象方法。
rest
参数
ES6引入 rest
参数,用于获取函数的实参,用来代替 arguments
function main(...args) {
//1、使用arguments获取实参
console.log(arguments);
//2、rest参数
console.log(args);
}
main(12, 23, 2, 2, 4, 12);
注意:
rest
参数非常适合不定个数参数函数的场景
spread
扩展运算符
扩展运算符(spread)也是三个点(...
)。它好比 rest
参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
//对象的展开
const skillOne = {
q: '天音波'
};
const skillTwo = {
w: '金钟罩'
};
const skillThree = {
e: '天雷破'
};
const skillFour = {
r: '猛龙摆尾'
};
const mangseng = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};
console.log(mangseng);
Symbol
ES6 引入了一种新的原始数据类型 Symbol
,表示独一无二的值。它是 JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
特点
- Symbol的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用
for...in
循环遍历,但是可以使用Reflect.ownKeys
来获取对象的所有键名
注: Symbol类型唯一合理的用法是用变量存储
symbol
的值,然后使用存储的值创建对象属性
Symbol内置值
除了定义自己使用的 Symbol 值以外,ES6 还提供了11个内置的Symbol值,指向语言内部使用的方法。
方法 | 作用 |
---|---|
Symbol.hasInstance | 当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法 |
Symbol.isConcatSpreadable | 对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。 |
Symbol.species | 创建衍生对象时,会使用该属性 |
Symbol.match | 当执行str.match(myObject) 时,如果该属性存在,会调用它,返回该方法的返回值。 |
Symbol.replace | 当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。 |
Symbol.search | 当该对象被str. search (myObject)方法调用时,会返回该方法的返回值。 |
Symbol.split | 当该对象被str. split (myObject)方法调用时,会返回该方法的返回值。 |
Symbol.iterator | 对象进行for...of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器 |
Symbol.toPrimitive | 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。 |
Symbol. toStringTag | 在该对象上面调用toString方法时,返回该方法的返回值 |
Symbol. unscopables | 该对象指定了使用with关键字时,哪些属性会被with环境排除。 |
迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator
接口,就可以完成遍历操作。
ES6创造了一种新的遍历命令for...of
循环,Iterator
接口主要供for...of
消费
原生具备iterator接口的数据(可用for...of
遍历)
- Array
- Arguments
- Set
- Map
- String
- TypedArray
- NodeList
工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next方法,指针自动指向数据结构的第一个成员
- 接下来不断调用next方法,指针一直往后移动,直到指向最后一个成员
- 每调用next方法返回一个包含value和done属性的对象
注: 需要自定义遍历数据的时候,要想到迭代器。
Promise
Promise是ES6引入的异步编程的新解决方案。语法上Promise是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果。
功能:写异步的代码,同步的执行出来,让代码更好的维护易读
同步:只有前一个任务执行完,才能继续执行下一个任务
异步:不进入主线程,进入任务队列,只有任务队列通知主线程,某个异步任务才可以执行,该任务才会进入主线程
- 每一个Promise实例都有3种状态:初始化(pending)、成功(fulfilled)、失败(rejected)
- 每一个Promise实例在刚被new出来的那一刻,状态都是初始化(pending)
- executor函数会接收到2个参数,它们都是函数,分别用形参:resolve、reject接收
async
和 await
async修饰的函数返回一个Promise对象,Promise实例的结果由async函数执行的返回值决定
await右侧的表达式一般为Promise实例对象, 但也可以是其它的值
- 如果表达式是Promise实例对象, await后的返回值是promise成功的值
- 如果表达式是其它值, 直接将此值作为await的返回值
await必须写在async函数中, 但async函数中可以没有await
如果await的Promise实例对象失败了, 就会抛出异常, 需要通过try...catch来捕获处理
Set
ES6 提供了新的数据结构 Set(集合)。它类似于数组,『但成员的值都是唯一』的
集合实现了iterator
接口,所以可以使用『扩展运算符』和for...of
进行遍历
集合的属性和方法
size
返回集合的元素个数add
增加一个新元素,返回当前集合delete
删除元素,返回boolean
值has
检测集合中是否包含某个元素,返回boolean
值clear
清空集合,返回undefined
Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
Map也实现了iterator接口,所以可以使用『扩展运算符』和for...of
进行遍历。
Map的属性和方法
size
返回Map的元素个数set
增加一个新元素,返回当前Mapget
返回键名对象的键值delete
删除某个键has
检测Map中是否包含某个元素,返回boolean
值clear
清空集合,返回undefined
class
类
ES6 提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。
通过class关键字,可以定义类。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
知识点
class
声明类constructor
定义构造函数初始化extends
继承父类super
调用父级构造方法static
定义静态方法和属性- 父类方法可以重写
get
和set
方法
class Person {
constructor(name) {
this.name = name
}
run() {
return '这是run方法'
}
}
const p = new Person('tom')
class Child extends Parent {
constructor() {
super()
}
}