ES6简介:
ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。
自ES6的发布后,解决了ES5 的先天不足,ES6新增了很多新特性,提高了开发人员的效率,以下简述ES6都有哪些新特性。
一、先了解下ECMAScript 和 JavaScript 的关系
要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。
该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。
因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现(另外的 ECMAScript 方言还有 JScript 和 ActionScript)。日常场合,这两个词是可以互换的。
二、ES6常用新特性
1、const 和 let
let:局部作用域,(在一对{}启用);不会变量提升;同作用域不能重复声明。
const:同let;声明只读常量,声明时必须初始化赋值。
2、箭头函数
this指向声明时所在的作用域,不能作为构造实例化对象,不能使用arguments变量。
const fn = (a, b) => { return a + b } fn(1, 1) // 输出2
3、模板字符串
简化字符串的拼接,模板字符串通过反引号(``)来表示,如果要嵌入变量通过"${变量名}"来实现。
const userInfo = { name: 'aliang', age: 24, } let str = `姓名是:${userInfo.name},年龄是:${userInfo.age}` console.log(str) // 姓名是:aliang,年龄是:24
4、默认参数
定义:为函数的形参设置默认值;
特点:①简洁;②易读;③便于维护。
function fn(a, b = 'b', c = 'c'){ console.log(a, b, c); } fn('a', 'b1'); // a, b1, c
5、解构赋值
定义:针对数组或者对象进行模式匹配,然后对其中的变量进行赋值;
特点:简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。
// 数组解构 let [a, b, c] = [1, 2, 3]; console.log(a, b, c) // 1, 2, 3 // 对象解构 let { foo, bar } = { foo: 'aaa', bar: 'bbb' }; console.log(foo, bar) // 'aaa', 'bbb'
6、Promise
Promise是ES6异步编程的一种解决方案,从语法上讲,Promise是一个对象或者说是构造函数,用来封装异步操作并可以获取其成功或失败的结果
promise的状态只能从 未完成->完成, 未完成->失败 且状态不可逆转
1、状态成功(resolve),进入then()得到异步任务的正确结果
2、状态失败(reject),进入catch()获取异常信息
function fn(flag) { return new Promise(function (resolve, reject) { setTimeout(() => { if (flag === true) { resolve('promise状态为成功!') } if (flag === false) { reject('promise状态失败!') } }, 2000) }) } fn(true) .then(res => { console.log(111111, res) // promise状态为成功!(2秒后执行) }) .catch(err => { console.log(222222, err) })
7、模块,Import 和 export
定义:
1、export命令:导出模块内部变量、方法等
2、import命令:导入别的模块的变量、方法等,并对其进行使用
特点:
1、在一个文件中,export、import可以有多个,export default仅有一个
2、通过export导出时,导入需要加{};而export default则不需要
例子
1、导出文件(export.js)
export const appId = '11111' export const appKey = '22222' export default defaultCity = '杭州'
2、导入文件(import.js)
import defaultCity from './export' import { appId, appKey } from './export.js' console.log('defaultCity==>', defaultCity) // 杭州 console.log('appId, appKey==>', appId, appKey) // 11111, 22222
8、class类的基本语法
8.1、class类的基本概念
class写法只是一个语法糖,它只是让对象原型的写法更加清晰,更像面向对象编程的语法
类和模块的内部默认都是严格模式
类不存在变量提升
8.2、constructor 方法
8.2.1、constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
class Point { } // 等同于 class Point { constructor() {} }
8.2.2、类的数据类型就是函数,类本身就指向构造函数。
class Point { // ... } typeof Point // "function" Point === Point.prototype.constructor // true
8.3、类的实例
class Point { // ... } // 报错 var point = Point(2, 3); // 正确 var point = new Point(2, 3);
与 ES5 一样,类的所有实例共享一个原型对象。
var p1 = new Point(2,3); var p2 = new Point(3,2); p1.__proto__ === p2.__proto__ // true
8.4、实例属性、静态属性、静态方法
ES6明确规定,Class内部只有静态方法,没有静态属性。
静态属性、静态方法的特点:
①不会被类实例所拥有的属性与方法,只是类自身拥有
②只能通过类调用
ES7有一个静态属性的提案,目前Babel转码器支持。
这个提案对实例属性和静态属性,都规定了新的写法。
8.4.1、类的实例属性
以前实例属性要在构造方法constructor里面定义,而es7中,类的实例属性可以用等式,直接写入类中。
react 中的例子
class ReactCounter extends React.Component { // 老写法 constructor(props) { super(props); this.state = { count: 0 }; } // es7新写法 state = { count: 0 }; }
8.4.2、类的静态属性
静态属性指的是Class本身的属性,即Class.propname,而不是定义在实例对象(this)上的属性。
// 老写法 class Foo { } Foo.prop = 1; // 新写法 class Foo { static prop = 1; }
8.4.3、类的静态方法
类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。
class Foo { static classMethod() { return 'hello'; } } Foo.classMethod() // 'hello' var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function
8.5、类的继承 extends
class Foo { // es7写法,静态属性 static age = 22 static classMethod() { return 'hello' } // es7写法,实例属性 state = { name: 'aLiang', } eatFoo = name => { return name } } class Bar extends Foo { // es6写法 // constructor(props) { // super(props) // this.sex = '男' // } // es7写法,实例属性 sex = '男' // 静态方法 static classMethod() { return super.classMethod() + ', too' } } const bar = new Bar() // 静态属性、静态方法的特点: // 1.可以被继承 // 2.只能通过类调用,类自身拥有 console.log(Bar.classMethod()) // 'hello, too' console.log(Bar.age) // 22 // 实例对象,不会访问静态属性、静态方法 console.log(bar.sex) // '男' console.log(bar.eatFoo('bar')) // 'bar' console.log(bar.state.name) // 'aLiang'
9、Set与Map
9.1、Set
9.1.1、什么是Set
Set是ES6新增的数据结构,类似数组,但是它的元素成员是唯一的
9.1.2、如何使用,属性和方法
9.1.2.1. 创建Set
① new Set()方式创建
let a = new Set()
② 通过传入数组方式创建
let a = new Set([1, 2, 'aliang'])
9.1.2.2. Set.size:返回Set中元素的数量
let a = new Set([1, 2, 'aliang'])
a.size // 3
9.1.2.3. Set.has(key):查找Set对象中是否存在key,返回一个布尔值
let a = new Set([1, 2, 'aliang'])
a.has('aliang') // true
9.1.2.4. Set.add(key):往Set对象中添加一个元素
let a = new Set()
a.add(1)
9.1.2.5. Set.delete(key):删除元素key
let a = new Set([1, 2, 'aliang'])
a.delete("aliang")
9.1.2.6. Set.clear(): 清空Set的全部元素
let a = new Set([1, 2, 'aliang'])
a.clear()
9.1.2.7. 遍历 Set
① forEach 遍历
let a = new Set([1, 2, 'aliang'])
a.forEach(item => {
console.log(item)
})
② for of 遍历
let a = new Set([1, 2, 'aliang'])
for(let item of a) {
console.log(item)
}
9.1.2.8. Set 转 数组
① 使用 Array.from 方法
let a = new Set([1, 2, 'aliang'])
let arr = Array.from(a)
② 使用扩展运算符
let a = new Set([1, 2, 'aliang'])
let arr = [...a]
9.1.3、Set的使用场景
可以利用元素成员唯一性,和方法has()是否有某个元素;如实现数组去重等等
代码实现
// 数组去重 let arr = [1, 1, 2, 3] let unique = [...new Set(arr)] // [1, 2, 3] let a = new Set([1, 2, 'aliang']) let b = new Set([2, 3, 4]) // 并集 let union = [...new Set([...a, ...b])] // [1, 2, 'aliang', 3, 4] // 交集 let intersect = [...new Set([...a].filter(item => b.has(item)))] // [2] // 差集 let difference = [ ...new Set([...a].filter(item => !b.has(item))), ...new Set([...b].filter(item => !a.has(item))), ] // [1, 'aliang', 3, 4]
9.2、Map
9.2.1、什么是Map
Map是ES6新增的数据结构,类似于对象,本质上就是键值对的集合,对象的键只能是字符串或者Symbols,但Map的键可以为任意类型
9.2.2、如何使用,属性和方法
9.2.2.1. 创建Map
① new Map()方式创建
let a = new Map()
② 通过传入二维数组方式创建
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
9.2.2.2. Map.size:返回Map对象中键值对数量
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
a.size // 2
9.2.2.3. Map.has(key):查找Map对象中是否存在key,返回一个布尔值
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
a.has('key1') // true
9.2.2.4. Map.set(key, value):设置Map对象的键值对(键名,键值),返回当前对象
let a = new Map()
a.set(0, 'zero')
a.set('key1', 'value1')
9.2.2.5. Map.get(key):返回key值对应的value,如果key不存在则返回undefined
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
a.get('key1') // value1
9.2.2.6. Map.delete(key):删除Map对象中键名为key的键值对
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
a.delete("key1")
9.2.2.7. Map.clear():移除Map对象中保存的所有键名/键值对
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
a.clear()
9.2.2.8. 遍历 Map
① forEach 遍历
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
a.forEach((value, key) => {
console.log(key, value)
})
② for of 遍历
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
for (let [key, value] of a) {
console.log(key, value)
}
9.2.2.9. Map.keys():返回一个新的Iterator对象 它包含按照顺序插入Map对象中每个元素的key值
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
for (let key of a.keys()) {
console.log(key)
}
9.2.2.10. Map.values():返回一个新的Iterator对象 它包含按照顺序插入Map对象中每个元素的value值
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
for (let value of a.values()) {
console.log(value)
}
9.2.2.11. Map.entries():该方法返回一个新的Iterator对象 它包含按顺序插入Map对象中每个[key,value]数组
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
for (let [key, value] of a.entries()) {
console.log(key, value)
}
9.2.2.12. Map 转 数组
① 使用 Array.from 方法
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
let arr = Array.from(a)
② 使用扩展运算符
let kvArray = [
['key1', 'value1'],
['key2', 'value2'],
]
let a = new Map(kvArray)
let arr = [...a]
9.2.3、Map的使用场景
不关心键值对的键名到底是什么,那么在这种情况下,你可以用Map
9.3、Set和Map总结
1、Set:是一组Key的集合,但不存储Value,由于Key不能重复,因此他最大的特点是所有的元素都是唯一的
2、Map:是键值对的集合,为JS带来了真正的键值存储机制;允许任何类型的键,具有极快的查找速度(存储键值较少的情况下)
参考来源:
https://blog.csdn.net/weixin_44246717/article/details/126307776
https://es6.ruanyifeng.com/#README
讨论数量:0