ES6 新特新
|字数总计:3.6k|阅读时长:14分钟|阅读量:2
H2 let 关键字
变量声明
1 2 3 4 5 6 7 8
| let a; let b,c,d; let e =100; let f = 521, g = 'iloveyou',h=[];
let star = '123' let star = '321'
|
块级作用域
1 2 3 4
| { let star = 'simple' } console.log(star);
|
不存在变量提升
1 2 3 4 5 6
| console.log(star) var star = 'simple'
console.log(star) let star = 'simple'
|
H2 const 关键字
const 定义常量
注意事项
一定要赋初始值
一般常量使用大写(潜规则)
常量的值不能修改
有块级作用域
对于数组和对象的元素修改,不算做对常量的修改,不会报错
1 2
| const TEAM = ['UZI','MXLG'] TEAM.push('Kobe')
|
H2 变量的解构赋值
ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
数组解构
1 2
| const F4 = ['科比','姚明','奥尼尔'] let [f1,f2,f3] = F4
|
对象的解构
1 2 3 4 5 6 7 8 9 10
| const obj = { name: 'SimpleLife', age: 18, height: 1.88, weight: function(){ } }
let {name,age,height} = obj
|
H2 模板字符串
- [``]内容中可以直接出现换行符
- 变量拼接
1 2 3 4 5
| let str = `<ul><li> 不会报错</li></ul`
let star1 = '123'; let star2 = `${star1}前面是123`;
|
H2 箭头函数
1 2 3 4 5 6 7 8 9 10 11
| let fn = function(){ }
let fn = (a,b)=>{ } let fn = a => { }
|
重要
- this值是静态的。this 始终指向函数声明时所在作用域下的 this 的值,没有自己的this
- 不能作为构造函数实例化对象
- 不能使用
arguments
变量
- 当形参只有一个的时候,可以简化括号。代码体只有一句,可以省略花括号
- 箭头函数不适合与 this 有关的回调,如事件回调,对象的方法
H2 rest 参数
1 2 3 4 5 6 7 8 9 10 11 12 13
| function data(){ console.log(arguments) } data('aaa','bbb','ccc')
function data(...args){ console.log(args) } data('aaa','bbb','ccc')
|
注意事项
1 2 3 4 5 6 7 8
| function fn(a,b,...args){ console(a) console(b) console(args) } fn(1,2,3,4,5,6)
|
H2 spred扩展运算符 …
1 2 3 4 5 6 7
| const arr = ['aaa','bbb','ccc']
function arrobj(){ console.log(arguments) } arrobj(arr); arrobj(...arr)
|
应用
合并数组
1 2 3
| const arr1 = ['123','456'] const arr2 = ['789','10'] const arr3 = [...arr1,...arr2];
|
将伪数组转为真正的数组
1 2
| const divs = document.querySelectorAll('div'); const divArr = [...divs];
|
H2 Symbol
H3 Symbol 基本使用
ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是js 语言的第一种数据类型,是一种类似字符串的数据类型
特点
- Symbol 的值是唯一的,用来解决命名冲突的问题
- 不能与其它数据进行运算
- Symbol 定义的对象属性不能使用 for…in 循环遍历,但是可以使用 Reflect.ownKeys 来获取对象的所有键名
1 2 3 4 5 6 7 8 9
| let s = Symbol() let s1 = Symbol('simplelife') let s2 = Symbol('simplelife')
let s4 = Symbol.for('simplelife') let s5 = Symbol.for('simplelife')
|
总结:JS数据类型
USONB: You Are So NiuBility
- undefined
- string
- symbol
- object
- null
- number
- boolean
Symbol 应用
- 给对象添加独一无二的属性和方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
let game ={...}
let methods = { up: Symbol(), down: Symbol() } game[methods.up] = function(){ } game[methods.down] = function(){ }
|
1 2 3 4 5 6 7 8 9 10
| let youxi = { name: '狼人杀', [Symbol('say')]: function(){ }, [Symbol('self')]: function(){ } }
|
H3 Symbol 内置值
H2 迭代器
迭代器(iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 iterator 接口,就可以遍历操作
ES6 创造了一种新的遍历命令 for…of 循环,iterator 接口主要提供 for…of 使用
原生具备 iterator 接口的数据(可用 for of 遍历)
- Array
- Arguments
- Set
- Map
- String
- TypeArray
- NodeList
工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的 next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用 next 方法,指针一直往后移动,直到指向最后一个成员
- 每调用 next 方法放回一个包含 value 和 done 属性的对象
注意:需要自定义遍历数据的时候,要想到迭代器
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| const CLASS = { name: '终极一班', stus:[ '小明','张三','李四','李华' ], [Symbol.iterator](){ let index = 0; return { next: ()=>{ if(index < this.stus.length){ const result = {value: this.stus[index],done:false} index++; return result; }else{ return {value: undefined,done:true} } } } } }
for (let v of CLASS) { console.log(v) }
|
H2 生成器
生成器是一个特殊的函数, 实现异步编程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| function * fn(){ } let iterator = fn() fn(); fn().next();
function * fn(){ console.log(111) yield '我是第一步'; console.log(222) yield '我是第二步' } let iterator = fn() console.log(iterator.next()) console.log(iterator.next())
|
H3 生成器函数参数
1 2 3 4 5 6
| function * fn(arg){ console.log(arg) }
let iterator = fn('AAA'); console.log(iterator.next());
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| function * fn(){ let one = yield 111; console.log(one) let two = yield 222; console.log(two) }
let iterator = fn()
console.log(iterator.next()); console.log(iterator.next('BBB'));
|
在第二次调用 next() 传入参数 ‘BBB’ ,改变了第一次 yield的返回值
实例:异步编程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| function one(){ setTimeout(()=>{ console.log(111) iterator.next(); },1000) } function two(){ setTimeout(()=>{ console.log(222) iterator.next(); },1000) } function three(){ setTimeout(()=>{ console.log(333) iterator.next(); },1000) }
function * fn(){ yield one(); yield two(); yield three(); }
let iterator = fn() iterator.next();
|
实例:模拟获取 用户数据 订单数据 商品数据 有先后顺序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| function getUsers(){ setTimeout(()=>{ let data = '用户数据' iterator.next(data) }) } function getOrders(){ setTimeout(()=>{ let data = '订单数据' iterator.next(data) }) } function getGoods(){ setTimeout(()=>{ let data = '商品数据' iterator.next(data) }) } function * gen(){ let users = yield getUsers(); console.log(users) let orders = yield getOrders(); console.log(orders) let goods = yield getGoods() console.log(goods) }
let iterator = gen() iteratro.next()
|
第一次调用了 next() 方法 执行生成器第一段 yield后面的 getUser() 方法。该方法执行的第二次 iteratro.next(data)
并传了data数据,该data数据会改变第一段yield后面值。
H2 Promise
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功后失败的结果
H2 Set
ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用 扩展运算符 和 for…of 进行遍历
集合的属性和方法
- size 返回集合的元素个数
- add 增加一个新元素,返回当前集合
- delete 删除元素,返回 boolean 值
- has 检查集合中是否包含某一个元素,返回 boolean 值
- clear 清空数组
let s = new Set(arr); s.clear()
注意
let s = new Set(arr)
传入数组,有去重复性
1 2
| let s = new Set(arr) lert news = [...s]
|
H2 Map
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是 “键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了 iterator 接口,所以可以使用 扩展运算符 和 for … of 进行遍历
Map 的属性和方法
- size 返回 Map 的元素个数
- set 增加一个新元素,返回当前 Map
- delete 删除元素
- get 返回键名对象的键值
- has 检测 Map 中是否包含某一个元素,返回 boolean 值
- clear 清空集合,返回 undefined
1 2 3 4 5 6 7 8
| let m = new Map()
m.set('name','SimpleLife') m.set('change',function(){ console.log('SimpleLife') })
|
H2 Class 类
ES6 提供了更接近传统语言的写法,引入了 Class(类) 这个概念,作为对象的模板。通过 class 关键字,可以定义类。基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| function Phone(brand,price){ this.brand = brand; this.price = price; }
Phone.prototype.call = function(){ console.log('我可以打电话') }
let Huawei = new Phone('华为',5999) Huawei.call() console.log(Huawei)
class Phone{ constructor(brand,price){ this.brand = brand this.price = price } call(){ console.log('我可以打电话') } }
let Huawei = new Phone('华为',5999) console.log(Huawei)
|
静态成员:不属于实例化对象的
1 2 3 4 5 6 7 8 9 10 11 12 13
| function Phone(){} Phone.name = '手机' Phone.change = function(){ console.log('静态成员')}
Phone.prototype.name = '手机'
class Phone{ static name = '手机'; static change = function(){ console.log('静态成员')} }
|
H3 构造函数继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| function Phone(brand,price){ this.brand = brand; this.price = price } Phone.prototype.call = function(){ console.log('我可以打电话') }
function SmartPhone(brand,price,color,size){ Phone.call(this,brand,price) this.color= color this.size = size }
SmartPhone.prototype = new Phone SmartPhone.prototype.constructor = SmartPhone
SmartPhone.prototype.photo = function(){ console.log('我可以拍照') } SmartPhone.prototype.playGame = function(){ console.log('我可以玩游戏') }
const huawei = new SmartPhone('华为','2200','银色','5.5inch') console.log(huawei)
|
H3 类继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| class Phone{ constructor(brand,price){ this.brand = brand; this.price = price; } call(){ console.log('我可以打电话') } }
class SmartPhone extends Phone{ constructor(brand,price,color,size){ super(brand,price); this.color = color; this.size = size; } photo(){ console.log('拍照') } playGame(){ console.log('打游戏') } }
const xiaom = new SmartPhone('小米',799,'黑色','4.7inch') xiaom.call() xiaom.photo() xiaom.playGame()
|
H3 子类对父类方法重写
在子类声明方法的时候,可以写同名父类方法,进行覆盖。当调用的时候,就是调用子类的方法
H3 Set 和 Get
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Phone{ get price(){ console.log('价格属性被读取了') return 'simplelife' } set price(value){ } }
let s = new Phone(); console.log(s.price) s.price = 'free'
|
H2 数值扩展
H3 EPSILON
Number.EPSILON
是 Javascript 表示最小精度,值接近于 2.22044604925031308084726333E-16
- 判断相等 当两数差的绝对值小于 EPSILON 表示相等
H3 二进制和八进制
1 2 3
| let b = 0b1010 let o = 0o777 let x = 0xff
|
H3 Number API
Number.isFinite
检测一个数值是否为有限数
Number.isNaN
检测一个数值是否为 NaN
Number.parseInt Number.parseFloat
字符串转整数
Number.isInteger
判断一个数是否为整数
Math.trunc
将数字的小数部分抹掉
Math.sign
判断一个数到底为正数 负数 零
H2 对象方法扩展
Object.is 判断两个值是否完全相等
1 2 3
| console.log(Object.is(150,150)) ; console.log(Object.is(NaN,Nan)) ; console.log(NaN === NaN)
|
Object.assign 对象的合并
1 2 3 4 5 6 7
| const config1 = { } const config2 = { } const sum = Object.assign(config1,config2)
|
H2 模块化
模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来
**模块化的好处 **
- 防止命名冲突
- 代码复用
- 高维护性
模块化规范
ES6之前的模块化规范有
CommonJS
=> NodeJS、Browserify
AMD
=> requireJS
CMD
=> seaJS
ES6 模块化语法
模块功能主要由两个命令构成:export 和 import
- export 命令用于规范模块的对外接口
- import 命令用于输入其它模块提供的功能
1 2 3 4 5 6 7 8 9 10 11
| export const BLOG = 'SimpleLife'
export function teach(){ console.log(BLOG) }
<script type="module"> import * as f from "./foo.js" </script>
|
完全暴露语法
默认暴露
1 2 3
| export default{ const BLOG = 'SimpleLife' }
|
导入方式
1 2 3 4 5 6 7 8 9 10 11
| import * as f from "./foo.js"
import {BLOG,teach} from "./foo.js"
import {default as sm} from "./foo.js"
import sm from './foo.js'
|
H3 babel 对 ES6 模块化代码转换
使用 babel对项目进行打包,转换成ES5语法,使得浏览器兼容
Babel中文文档