前言
ECMAScript 6.0(简称ES6)是 JavaScript 语言的下一代标准。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
1.let const
在es6之前,定义变量都是使用var,但是var存在一些问题,比如可以重复声明,仅支持函数作用域问题。所以es6设计了let和const来弥补不足的地方。let和const具备哪些特性?
let
- 在块作用域内有效
- 不能重复声明
- 不会预处理, 不存在提升
- 应用:循环遍历加监听
const
- 不能重复声明
- 块级作用域
- 不可修改const变量的值
- 注意事项:一定要赋初始值,一般常量要大写(潜规则)
对于数组和对象的元素修改,不算做常量的修改,不会报错
2.块作用域
es5只有全局作用域和函数作用域,没有块级作用域:
var temp = new Date();
function f() {
console.log(temp);
if (false) {
var tmp = "hello world";
}
}
f(); // undefined
- es6的块级作用域:
function f1() {
let n = 5;
if (true) {
let n = 10;
}
console.log(n); // 5
}
- es6的块级作用域声明函数只在使用大括号的情况下成立:
// 不报错
'use strict';
if (true) {
function f() {}
}
// 报错
'use strict';
if (true)
function f() {}
3.扩展运算符
将一个数组转化为逗号分隔的参数序列
console.log(...[1, 2, 3])
// 1 2 3
console.log(1, ...[2, 3, 4], 5)
// 1 2 3 4 5
[...document.querySelectorAll('div')]
// [<div>, <div>, <div>]
{...{a: 1}, ...{a: 2, b: 3}}
// {a: 2, b: 3}
[...[1], ...[2, 3]]
// [1, 2, 3]
const arr = [1]
arr.push(...[2, 3])
// arr:[1, 2, 3]
4.模板字符串
模板字符串 : 简化字符串的拼接
- 模板字符串必须用 `` 包含
- 变化的部分使用${xxx}定义
var str = `abcdefgh`;
console.log(str);
let name = "小明";
function a() {
return "ming";
}
console.log(`我的名字叫做${name},年龄${17+2}岁,性别${'男'},游戏ID:${a()}`);
5.变量的解构赋值
ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值
//1数组的结构
const F=['你','好']
let [ni,hao]=F
console.log(ni)
console.log(hao)
//2对象的结构
const zhap={
name:'篮球'
}
let {name}=zhap;
console.log(name)
6.箭头函数
不能作为构建实例化对象
不能使用arguments变量
// 声明一个函数
let f=function f(){
console.log("一般函数")
}
// 箭头函数
let jia=()=>{
console.log("箭头函数")
}
// 箭头函数的简写
// 当只有一个参数的时候,省略小括号
let t= n =>{
return n+1
}
console.log(t(1))
//省略花括号,当代码体只有一句语句的时候,此时return必须省略,而且语句的执行结果就是函数的返回值
let pow =(n)=> n*n;
console.log(pow(2))
7.函数参数默认值
ES6中允许函数参数赋值初始值
//形参初始值,具有默认参数一般靠后
function add(a,b,c=10){
return a+b+c
}
let result=add(1,2)
console.log(result) //13
8.rest参数
用于获取函数的实参,代替ES5中的arguments
- ES5 arguments对象
function data1(a,b) {
console.log(arguments[2]);//3 //打印第三个参数
}
data1(1,2,3,4)
- ES6 ...args
function data(a,b,...args) {
console.log(args); //3,4
}
data(1,2,3,4);
9.Set 数据结构
类似于数组,但是成员变量都是唯一的,没有重复,Set本身是一个构造函数。
const s = new Set([1,2,2,3,4]);
console.log([...s]);//1,2,3,4
//可用于数组去重
- Set 实例的属性和方法
- size 数据的长度
- add() 添加某个值,返回 Set 结构本身。
- delete() 删除某个值,返回一个布尔值,表示删除是否成功。
- has() 查找某条数据,返回一个布尔值。
- clear() 清除所有成员,没有返回值。
const s = new Set();
s.add('zs'); //s:['zs]
s.size(); //1
s.has('zs); //true
s.delete('zs);
- Set 遍历操作
- keys(): 返回键名的遍历器。
- values(): 返回键值。
- entries: 返回键值对。
- forEach(): 使用回调函数遍历每个成员。
//遍历
const s = new Set([1,3,5]);
for( let i of s.keys()){
console.log(i); //1,3,5
}
for( let i of s.values()){
console.log(i); //1,3,5
}
for( let i of s.entries()){
console.log(i); //[1:1],[3:3],[5:5]
}
s.forEach((value,key)=>{
console.log(value); //1,3,5
})
10.Map()
类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以作为键。
- Set 实例的属性和方法
- size 数据的长度
- add() 添加某个值,返回 Set 结构本身。
- delete() 删除某个值,返回一个布尔值,表示删除是否成功。
- has() 查找某条数据,返回一个布尔值。
- clear() 清除所有成员,没有返回值。
- get(key)
7.set(key,value)
const map = new Map();
map.set("name","zhangsan")
map.get("name");
11.symbol
ES6引入的一种新的原始类型Symbol,表示独一无二的值,他是javascript语言的第七种数据类型,是一种类似字符串的数字类型(已有的原始数据类型:String, Number, boolean, null, undefined, Object).
- Symbol的特点:
- Symbol属性对应的值是唯一的,解决命名冲突问题。
- Symbol值不能与其它数据进行计算,包括同字符串拼串。
- for in,for of 遍历不会遍历Symbol属性。
// 创建Symbol
let s=Symbol('你哈哈')
console.log(s)
let s2=Symbol('你哈哈')
console.log(s===s2)//flase
//为对象添加Symbol属性
let youxi={
name:'狼人杀',
[Symbol('say')]:function(){
console.log("我可以发言")
},
[Symbol('look')]:function(){
console.log("我可以自爆")
}
}
12.迭代器(iterator)
迭代器是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署了iterator接口,就可以完成遍历操作。
作用:
- 为各种数据,提供一个统一的、简便的访问接口。
- 使得数据结构的成员能够按某种次序排列。
- es6 创造了一种新的遍历命令 for of 循环,iterator接口主要提供for of 消费。
- 原生具备iterator接口的数据(可用for of遍历)
1、Array
2、arguments
3、set容器
4、map容器
5、String
6、TypedArray
7、NodeList
let iter = 'hello';
let itera = iter[Symbol.iterator]();
console.log(itera.next()); //{value: 'h', done: false}
console.log(itera.next());//{value: 'e', done: false}
console.log(itera.next());//{value: 'l', done: false}
for(let i of itera){
console.log(i); // l o
}
13.Generator 生成器函数
函数使用 * 。
- es6 提供的解决异步编程的方案之一。
- Generator函数是一个状态机,内部封装了不同状态的数据。
- 用来生成遍历器对象。
- 可暂停函数(惰性求值),yield可暂停,next方法可启动,每次返回的是yield后的表达式结果。
//yield函数代码分隔符
function * gen() {
console.log('函数开始执行');
yield console.log('1');
console.log('函数暂停后再次启动');
yield console.log('2');
}
//利用next方法来向下执行
let iterator = gen();
iterator.next(); //函数开始执行 1
iterator.next(); //函数暂停后再次启动 2
14.Promise
1、含义
异步编程的解决方案,可以将异步的操作以同步的流程表达出来,避免了层层的回调函数(“回调地狱”)
ES6中promise是一个构造函数,用来生成promise实例
2、promise对象的两大特点:
对象的状态不受外界的影响,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),只有异步操作能决定当前哪一种状态一旦状态改变,就不会在改变,任何时候都是这种结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生了,状态就固定了,不会在变了,称为resolved(已定型)。
var promise = new Promise((resolve, reject) => {
var success = true;
if (success) {
resolve('成功');
} else {
reject('失败');
}
}).then((data) => { console.log(data)}
).catch(err=>{
console.log(err)
})
15. async await
- async
async其实就是对 Generator的封装,只不过async可以自动执行next()。
async返回值
1.默认返回一个Promise,如果return不是一个Promise对象,就会被转化为立即resolve的Promise,可以在then函数中获取返回值。
2.async 必须等到里面所有的await 执行完, async 才开始 return ,返回的Promise 状态才改变,除非遇到return 和错误。
async function fn () {
await console.log('100');
await console.log('200');
return 300
}
fn().then(res => {
console.log(res) // 300
})
//打印顺序 100 200 300
- await
1.await也是默认返回 Promise 对象,如果 await 后面不是一个 Promise 对象,就会转为立即 resolve 的 Promise。
2.如果一个await 后面的 Promise 如果为 reject, 那么整个async 都会中断执行,后面的await都不会执行,并且抛出错误,可以在 async 的 catch 总捕获错误。
async function f() {
await Promise.reject('error');
await Promise.resolve('hello world'); // 不会执行
}
f().then(res =>{
}).catch(err=>{
console.log(err) // error
})
16.class
ES6 提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
如何定义一个class类:
class User {
constructor(name) { // 构造器,相当于es5中的构造函数
this.name = name // 实例属性
}
showName(){ // 定义类的方法,不能使用function关键字,不能使用逗号分隔
console.log(this.name)
}
}
var foo = new User('foo')
- constructor
1.ES 6 中class 类专用的构造器,相当于之前定义的构造函数,每个类都必须有constructor,如果没有则自动添加一个空的 constructor 构造器。
2.创建实例的时候自动执行 constructor 函数
3.constructor 中的 this 指向实例,并且默认返回 this(实例)。
- class 类的 prototype
其中class 的基本类型就是函数(typeof User = ‘function’),既然是函数,那么就会有prototype属性。
类的所以方法都是定义在prototype上:
class User {
constructor() {
// ...
}
toString() {
// ...
}
toValue() {
// ...
}
}
User.toValue() // err User.toValue is not a function
User.prototype.toValue() // 可以调用toValue方法
// 等同于
User.prototype = {
constructor() {},
toString() {},
toValue() {},
};
- 类的实例
- 类的实例只能通过 new 来创建
- 除了静态方法,定义在类上的所有的方法都会被实例继承
- 除非定义在类的 this 对象上才是实例属性,否则都是定义在类的原型(prototype)上。
//定义类
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
var point = new Point(2, 3);
point.toString() // (2, 3)
point.hasOwnProperty('x') // true
point.hasOwnProperty('y') // true
point.hasOwnProperty('toString') // false
point.__proto__.hasOwnProperty('toString') // true
- 静态方法
如果在类中定义一个方法的前面加上 static 关键字,就表示定义一个静态方法,静态方法不会被实例继承,但会被子类继承,所以不能通过实例使用静态方法,而是通过类直接调用。
class User {
constructor(name){
this.name = name
}
static show(){
console.log('123')
}
}
class VipUser extends User{}
VipUser.show() // 123
User.show() // 123
var foo = new User('foo')
foo.show() // foo.show is not a function
- 静态属性
- class 的静态属性指的是 Class 本身的属性,目前只能通过 Class.propName 定义静态属性
- 静态属性可以被子类继承,不会被实例继承。
class User{}
User.name = 'foo' // 为class定义一个静态属性
class VipUser extends User{}
console.log(VipUser.name) // foo
var foo = new User()
console.log(foo.name) // undefined
网友评论