ES6新特性
文章目录
- 一、ECMASript 介绍
- 二、ES6 新特性
- 2.1 let、const 关键字
- 2.2 变量的解构赋值
- 2.3 模板字符串
- 2.4 对象简写写法
- 2.6 箭头函数
- 2.7 函数参数默认值
- 2.8 rest 参数
- 2.9 spread 扩展运算符
- 2.10 Symbol
- 2.11 迭代器
- 2.12 生成器 generator 函数
- 2.13 Promise 的使用
- 2.14 Set
- 2.15 Map
- 2.16 class 类
- 2.17 数值扩展
- 2.18. 对象扩展
- 2.19. 模块化
一、ECMASript 介绍
ECMA
(European Computer Manufacturers Association
)中文名称为欧洲计算机制造商协会,这个组织的目标是评估、开发和认可电信和计算机标准。1994年后该组织改名为ECMA
国际。
ECMAScript
是由ECMA
国际通过 ECMA-262 标准化的脚本程序设计语言。
ECMA-262
(ECMAScript
) 历史版本查看网址:
版本 | 年份 | 说明 |
---|---|---|
第1版 | 1997年 | 制定了语言的基本语法 |
第2版 | 1998年 | 较小改动 |
第3版 | 1999年 | 引入正则、异常处理、格式化输出等。IE开始支持 |
第4版 | 2007年 | 过于激进,未发布 |
第5版 | 2009年 | 引入严格模式、JSON,扩展对象、数组、原型、字符串、日期方法 |
第6版 | 2015年 | 模块化、面向对象语法、Promise、箭头函数、let、const、数组解构赋值等等 |
第7版 | 2016年 | 幂运算符、数组扩展、Async/await关键字 |
第8版 | 2017年 | Async/await、字符串扩展 |
第9版 | 2018年 | 对象解构赋值、正则扩展 |
第10版 | 2019年 | 扩展对象、数组方法 |
ES.next | 动态指向下一个版本 |
谁在维护ECMA-262
?
TC39
(Technical Committee 39
)是推进ECMAScript
发展的委员会。其会员都是公司(其中主要是浏览器厂商,有苹果、谷歌、微软、因特尔等)。TC39
定期召开会议,会议由会员公司的代表与特邀专家出席
ES6
的好处:
- 版本变动内容最多,具有里程碑意义
- 加入许多新的语法特性,编程实现更简单、高效
- 前端发展趋势,就业必备技能
二、ES6 新特性
2.1 let、const 关键字
① let 关键字
let
关键字用来声明变量,使用let
声明的变量有几个特点:
- 不允许重复声明
- 块级作用域
- 不存在变量提升
- 不影响作用域链
应用场景:声明变量都使用let
② const 关键字
const
关键字用来声明常量,const
声明有以下特点:
- 声明必须赋初始值
- 标识符一般为大写
- 不允许重复声明
- 值不允许修改
- 块儿级作用域
注意: 对象属性修改和数组元素变化不会触发const
错误
应用场景:声明对象类型使用const
,非对象类型声明选择let
③ var与let、const的区别
var
声明的变量均为全局变量,而let
和const
声明的变量均为局部变量var
声明变量存在变量提升,let
和const
不存在变量提升,即var
定义的变量可以先使用后定义- 同一作用域下
let
和const
不能声明同名变量,而var
可以 暂存死区
var a = 100;
if(1){
a = 10;//就近原则
//在当前块作用域中存在a使用let/const声明的情况下,给a赋值10时,只会在当前作用域找变量a,
//而这时,还未到声明时候,所以控制台Error:a is not defined
let a = 1;
}
2.2 变量的解构赋值
ES6
允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。
注意:频繁使用对象方法、数组元素,就可以使用解构赋值形式。
/** * 数组 */
const city = ['Beijing', 'Shanghai', 'Guangzhou', 'Shenzhen']
let [bj, sh, gz, sz] = city
//Beijing Shanghai Guangzhou Shenzhen
console.log(bj + " " + sh + " " + gz + " " + sz)
/** * 对象 */
const person = {
name: 'jack',
age: 21
}
let {
age
} = person
//21
console.log(age)
2.3 模板字符串
模板字符串是增强版的字符串,用反引号(`)标识,特点:
- 字符串中可以出现换行符
- 可以使用
${xxx}
形式输出变量
注意:当遇到字符串与变量拼接的情况使用模板字符串。
let name = 'jack'
//我的名字是jack
console.log('我的名字是'+`${ name}`)
name = 'rose'
//我的名字是rose
console.log('我的名字是'+`${ name}`)
2.4 对象简写写法
ES6
允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
const name ='jack'
const eat = function(){
console.log('eat......')
}
const person = {
name,
eat,
//方法的简写
sleep(){
console.log('sleep......')
}
}
person.sleep()
person.eat()
2.6 箭头函数
ES6
允许使用箭头(=>
)定义函数。箭头函数的注意点:
- 如果形参只有一个,则小括号可以省略
- 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的执行结果
- 箭头函数this指向声明时所在作用域下
this
的值 - 箭头函数不能作为构造函数实例化
不能使用
arguments
//1、箭头函数的使用
let add = (a, b) => {return a + b
}
console.log(add(1, 1))//2//2、this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
function getName() {console.log(this.name)
}
const getName2 = () => {console.log(this.name)
}
window.name = ‘北京’;
const city = {name: "Beijing",
remark:"centre"
}
getName()//北京
getName2()//北京
getName.call(city);//Beijing
getName2.call(city);//北京//2. 不能作为构造实例化对象
// let Person = (name, age) => {
// this.name = name;
// this.age = age;
// }
// const me = new Person(‘xiao’,30);//Person is not a constructor//3. 不能使用 arguments 变量
// let fn = () => {
// console.log(arguments);
// }
// fn(1,2,3);//arguments is not defined
箭头函数不会更改this指向,用来指定回调函数会非常合适
2.7 函数参数默认值
//1、ES6允许给函数参数赋值初始值, 一般位置要靠后(潜规则)
const add = (a, b, c = 10) => {
return a + b + c
}
console.log(add(1,2,3))//6
console.log(add(1,2))//13
//2、与解构赋值结合
function connect({ host="127.0.0.1", username,password, port}){
console.log(host)
console.log(username)
console.log(password)
console.log(port)
}
connect({
host: 'mysql.com',
username: 'root',
password: 'root',
port: 3306
})
2.8 rest 参数
ES6
引入rest
参数,用于获取函数的实参,用来代替arguments
;
注意:rest
参数非常适合不定个数参数函数的场景。
/** * 作用与 arguments 类似 */
function add(...args){
console.log(args);
}
add(1,2,3,4,5);
/** * rest 参数必须是最后一个形参 */
function minus(a,b,...args){
console.log(a,b,args);
}
minus(100,1,2,3,4,5,19);
2.9 spread 扩展运算符
扩展运算符(spread
)也是三个点(…)。它好比rest
参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。
const heros = ['德莱厄斯', '德莱文']
function show() {
console.log(arguments)
}
show(...heros) ///[Arguments] { '0': '德莱厄斯', '1': '德莱文' }
const skillOne = { q: '致命打击' }
const skillTwo = { w: '勇气' }
const skillThree = { e: '审判' }
const skillFour = { r: '德玛西亚正义' }
const gailun = { ...skillOne, ...skillTwo, ...skillThree, ...skillFour }
console.log(gailun) //{ q: '致命打击', w: '勇气', e: '审判', r: '德玛西亚正义' }
2.10 Symbol
① Symbol 基本使用
ES6
引入了一种新的原始数据类型Symbol
,表示独一无二的值。它是JavaScript
语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol
特点:
Symbol
的值是唯一的,用来解决命名冲突的问题Symbol
值不能与其他数据进行运算Symbol
定义的对象属性不能使用for...in
循环遍历,但是可以使用Reflect.ownKeys
来获取对象的所有键名;使用Object.getOwnPropertySymbols
来获取对象的所有Symbol
键名
注: 遇到唯一性的场景时要想到Symbol
//1、Symbol的基本使用
let s1 = Symbol()
console.log(s1, typeof s1)//Symbol() 'symbol'
//2、添加标识的Symbol
let s2 = Symbol('Beijing')
let s3 = Symbol('Beijing')
console.log(s2 == s3)//false
//3、使用Symbol.for定义
let s4 = Symbol.for('Shanghai')
let s5 = Symbol.for('Shanghai')
console.log(s4 == s5)//true
//4、不能与其他数据进行运算
let s6 = s2 + "city"//Cannot convert a Symbol value to a string
② Symbol创建对象属性
let person = {
name:"Jack",
//创建独一无二的Symbol属性方法
[Symbol('say')]: function(){
console.log("我可以说话")
},
[Symbol('draw')]: function(){
console.log('我可以画画');
}
}
const symbolProperties = Object.getOwnPropertySymbols(person)
person[symbolProperties[0]]()//我可以说话
const allProperties = Reflect.ownKeys(person)
person[allProperties[2]]()//我可以画画
③ 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环境排除 |
class Person{
static[Symbol.hasInstance](param){
console.log(param)//{ name: 'jack' }
return true
}
}
let o ={ name :'jack'}
console.log(o instanceof Person)//true
const arr = [1,2,3];
const arr2 = [4,5,6];
arr2[Symbol.isConcatSpreadable] = false;
//[ 1,2,3,[ 4, 5, 6, [Symbol(Symbol.isConcatSpreadable)]: false ] ]
console.log(arr.concat(arr2));
2.11 迭代器
遍历器(Iterator
)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator
接口,就可以完成遍历操作。
ES6
创造了一种新的遍历命令for...of
循环,Iterator
接口主要供for...of
消费。原生具备iterator
接口的数据类型:Array
、Arguments
、Set
、Map
、String
、TypedArray
、NodeList
。
工作原理:
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的
next
方法,指针自动指向数据结构的第一个成员 - 接下来不断调用
next
方法,指针一直往后移动,直到指向最后一个成员 每调用
next
方法返回一个包含value
和done
属性的对象//1、使用for…of遍历数组
const heros = [‘盖伦’,’拉克丝’,’赵信’]for (let hero of heros) {
console.log(hero)
}
//2、使用iterator
const itr = herosSymbol.iterator
console.log(itr.next())//{ value: ‘盖伦’, done: false }
console.log(itr.next())//{ value: ‘拉克丝’, done: false }
console.log(itr.next())//{ value: ‘赵信’, done: false }
console.log(itr.next())//{ value: undefined, done: true }
2.12 生成器 generator 函数
生成器函数是ES6
提供的一种异步编程解决方案,语法行为与传统函数完全不同。说明:
*
的位置没有限制- 生成器函数返回的结果是迭代器对象,调用迭代器对象的
next
方法可以得到yield
语句后的值 yield
相当于函数的暂停标记,也可以认为是函数的分隔符,每调用一次next
方法,执行一段代码next
方法可以传递实参,作为yield
语句的返回值/* generator生成器函数的使用 /
function gen() {yield 'a'
yield 'b'
yield 'c'
}
let itr = gen()
for (let v of itr) {console.log(v) // a b c
}
/* 带参数的生成器函数 /
function gen2(arg) {console.log("arg=" + arg)// arg=a
let r1 = yield 111
console.log("arg=" + r1)// arg=b
let r2 = yield 222
console.log("arg=" + r2)// arg=c
let r3 = yield 333
console.log("arg=" + r3)// arg=d
}
let itr2 = gen2(‘a’)
console.log(itr2.next())// { value: 111, done: false }
console.log(itr2.next(‘b’))// { value: 222, done: false }
console.log(itr2.next(‘c’))// { value: 333, done: false }
console.log(itr2.next(‘d’))// { value: undefined, done: true }
generator
函数的作用:
generator
可以在执行过程中多次返回变量状态的函数- 把异步回调代码变成同步代码,使代码变得有层次感,不需要大量的嵌套
① 生成器函数实际应用-解决回调地狱
//原方法
setTimeout(() => {
setTimeout(() => {
setTimeout(() => {
}, 1000);
}, 1000);
}, 1000);
//使用generator函数
function func() {
setTimeout(() => {
iterator.next();
}, 1000)
}
function* gen4() {
yield func()
yield func()
yield func()
}
const iterator = gen4()
iterator.next()
② 生成器函数实际应用-顺序调用方法
//模拟获取用户数据、订单数据、商品数据
function execute(data) {
setTimeout(()=>{
itr5.next(data);
}, 1000);
}
function * gen5(args){
let users = yield execute('用户数据');
console.log(users)//用户数据
let orders = yield execute('订单数据');
console.log(orders)//订单数据
let goods = yield execute('商品数据');
console.log(goods)//商品数据
}
let itr5 = gen5();
itr5.next();
2.13 Promise 的使用
详细见 Promise 的使用
2.14 Set
ES6
提供了新的数据结构Set
(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator
接口,所以可以使用扩展运算符和or...of...
进行遍历,集合的属性和方法:
size
:返回集合的元素个数add
:增加一个新元素,返回当前集合delete
:删除元素,返回boolean
值has
:检测集合中是否包含某个元素,返回boolean
值clear
:清空集合,返回undefined
//创建一个空集合
let s = new Set()
//创建一个非空集合
let s1 = new Set([1, 1, 2, 2, 3, 3, 4])
console.log(s1)//Set { 1, 2, 3, 4 }
console.log(s1.size)//4
console.log(s1.delete(1))//true
console.log(s1)//Set { 2, 3, 4 }
console.log(s1.has(2))//true
s1.clear()
console.log(s1)//Set {}
2.15 Map
ES6
提供了Map
数据结构。它类似于对象,也是键值对的集合。但是键的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map
也实现了iterator
接口,所以可以使用扩展运算符和for...of...
进行遍历。Map
的属
性和方法:
size
:返回Map
的元素个数set
:增加一个新元素,返回当前Map
get
:返回键名对象的键值has
:检测Map
中是否包含某个元素,返回boolean
值clear
:清空集合,返回undefined
//创建一个空map
let m = new Map()
//创建一个非空map
let m1 = new Map([[‘name’,’jack’],[‘age’,18]])
console.log(m1)//Map { ‘name’ => ‘jack’, ‘age’ => 18 }
console.log(m1.size)//2
m1.set(‘age’,20)
console.log(m1)//Map { ‘name’ => ‘jack’, ‘age’ => 20 }
console.log(m1.has(‘name’))//true
m1.clear()
console.log(m1)//Map {}
2.16 class 类
ES6
提供了更接近传统语言的写法,引入了Class
(类)这个概念,作为对象的模板。通过class
关键字,可以定义类。基本上,ES6
的class可以看作只是一个语法糖,它的绝大部分功能,ES5
都可以做到,新的class
写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。知识点:
class
声明类constructor
定义构造函数初始化extends
继承父类super
调用父级构造方法static
定义静态方法和属性父类方法可以重写
//父类
class Phone {//构造方法
constructor(brand, color, price) {
this.brand = brand;
this.color = color;
this.price = price;
}
//对象方法
call() {
console.log('我可以打电话!!!')
}
}
//子类
class SmartPhone extends Phone {constructor(brand, color, price, size) {
super(brand, color, price)
this.size = size
}
//子类方法
photo() {
console.log('我可以拍照!!!')
}
//重写父类方法
call() {
console.log('我可以打视频电话!!!')
}
static playGame(){
console.log('我可以打游戏!!!')
}
}
//实例化对象
const Nokia = new Phone(‘诺基亚’, ‘灰色’, 230)
const iPhone12 = new SmartPhone(‘苹果’, ‘白色’, 5488, ‘6.2inch’)
iPhone12.photo()//调用重写方法
iPhone12.call()//调用重写方法
SmartPhone.playGame()//调用静态方法
2.17 数值扩展
//1、Number.EPSILON 是 JavaScript 表示的最小精度,接近于 2.2204460492503130808472633361816E-16
function equal(a, b) {
if (Math.abs(a - b) < Number.EPSILON) {
return true
} else {
return false
}
}
console.log(0.1 + 0.2 == 0.3)//false
console.log(equal(0.1 + 0.2, 0.3))//true
//2、0b二进制、0o八进制、0x十六进制
console.log(0b1010)//10
console.log(0o777)//511
console.log(100)//100
console.log(0xff)//255
//3、Number.isFinite 检测一个数值是否为有限数
console.log(Number.isFinite(100))//true
console.log(Number.isFinite(100/0))//false
console.log(Number.isFinite(Infinity))//false
//4、Number.isNaN 检测一个数值是否为 NaN
console.log(Number.isNaN(123)) //false
//5. Number.parseInt Number.parseFloat字符串转整数
console.log(Number.parseInt('5211314love'))//5211314
console.log(Number.parseFloat('3.1415926神奇'))//3.1415926
//6. Number.isInteger 判断一个数是否为整数
console.log(Number.isInteger(5))//true
console.log(Number.isInteger(2.5))//false
//7. Math.trunc 将数字的小数部分抹掉
console.log(Math.trunc(3.5))//3
//8. Math.sign 判断一个数到底为正数 负数 还是零
console.log(Math.sign(100))//1
console.log(Math.sign(0))//0
console.log(Math.sign(-20000))//-1
2.18. 对象扩展
ES6
新增了一些Object
对象的方法
Object.is
:比较两个值是否严格相等,与===
行为基本一致(包括NaN
)Object.assign
:对象的合并,将源对象的所有可枚举属性,复制到目标对象__proto__
、setPrototypeOf
:setPrototypeOf
:可以直接设置对象的原型//1、Object.is 判断两个值是否完全相等
console.log(1 === 1) //true
console.log(Object.is(NaN, NaN)) //true
console.log(NaN === NaN) //false//2、Object.assign 对象的合并
const config1 = {host: 'localhost',
port: 3306,
custom1: '1'
}
const config2 = {host: '127.0.0.1',
port: 3307,
custom2: '2'
}
console.log(Object.assign(config1, config2))//3. Object.setPrototypeOf 设置原型对象 Object.getPrototypeof
const school = {name: 'Peking'
}
const cities = {location: ['北京','上海','深圳']
}
Object.setPrototypeOf(school, cities)
console.log(Object.getPrototypeOf(school))//{ location: [ ‘北京’, ‘上海’, ‘深圳’ ] }
console.log(school)//{ name: ‘Peking’ }
2.19. 模块化
详细见 ES6 模块化
还没有评论,来说两句吧...