ES6

ES6

let + const

函数作用域function(){}
var 可以重新赋值 会有变量提升

块作用域{}
let 可以重新赋值 在for循环中属于整个循环
const 不可以重新赋值 对象属性可以修改如 person.age = xxx object.freeze(person) 什么都不允许修改

用来代替立即执行函数
{
const name = 'ruoyu'
}

用于for循环
for(let i = 1; i < 10; i++){
console.log(i)
setTimeout(function(){
console.log(i:${i})
},1000)
}

临时性死区
临时性死区 就是指 let 和 const 有变量提升 但是表现不出来 等于没有变量提升 不能在声明前console.log

es6中如何使用var let const
默认使用const
当变量需要重新绑定或者更新的时候使用let
尽量不使用var


箭头函数

箭头函数的声明
删掉function关键字
加上一个 => 箭头
没有参数加() 一个参数可选择()写/不写 多个参数逗号分隔(1,2)
get(1,2) => {
return 1 + 2
}

箭头函数隐式返回
把return删除 删掉花括号{} 把函数写到一行 如:(number) => number * 2
get(1,2) => 1 + 2

箭头函数的this
是词法作用域 在定义的时候就被指定 不存在this值的绑定 箭头函数的this指的自己的父级元素的this值

es6函数默认值
function age(a = 18, b = 20) => {
return a * b
}

哪些情况下不宜使用箭头函数:
1、作为构造函数 或者一个方法需要绑定到对象的时候 如 Person.prototype.updatePoints = () =>{}
2、当你真需要this的时候 如click事件对象 this会是windows 所以改用旧版函数 function
3、需要使用arguments对象的时候 箭头函数没有arguments 所以改用旧版函数 function


模板字符串

${} 花括号里面${}可以是变量 也可以是js表达式 对象的属性 函数 ``可以嵌套

{
const person = 'jelly'
const age = '5'
const sentence = ${person} is ${age * 5} years old.

const template =

Hello

.trim()
}

字符串删除空格.trim()

.trim() 因为``里会默认保留html的空格 所以需要删除空格

模板字符串使用
{
const jelly = {
name: 'jelly',
date: '2017-05-07'
todos: [
{name: 'Go to Store', completed: false},
{name: 'Watch Movie', completed: true},
{name: 'Running', completed: true}
]
}
}

const template =

    ${jelly.todos.map(todo =>

  • {todu.completed ? '√' : '×'} //这里使用三元表达式 if如果是真[?] 返回√ else[:]返回×
  • ).join('')}

document.body.innerHTML = template


标签模板字符串(模板字符串高级)
在模板字符串前使用 函数名 定义这个函数 这个函数接收模板字符串作为参数
函数的参数1 是一个数组 由模板字符串里的 普通字符串组成
函数的参数23456... 是由模板字符串里的变量组成 每个变量对应一个参数

function highlight(strings,...values){
const highlighted = valures.map(value => ${values})
return strings.reduce((prev.curr,index) => ${prev}${curr}${highlighted[i] || ''},'')
}

const user = 'Mary'
const topic = 'Learn to use markdown'
const sentence = highlight${user} has commented on your topic ${topic}

标签模板过滤用户输入:引入净化工具[DOMPurify] 用标签模板字符串处理用户输入 对用户的输入做出一定的净化


ES6新增字符串方法函数
1.startsWith("参数",从哪一位开始如6) 从第一位计算

const id = '51030019800730366x'
id.startsWith('51') //true
id.startsWith('1980',6) //true

const fan = 'I love Laravist.' 大小写敏感
fan.startsWith('i') //false


2.endsWith("参数1",从哪一位开始如6) 从最后计算 大小写敏感

const id = '51030019800730366x'
id.endsWith('x') //true
id.endsWith('love',6) //true


3.includes("参数1",从哪一位开始如6) 是否包含
const fan = 'I love Laravist.' 大小写敏感
fan.includes('Laravist') //true
fan.includes('Laravist',10) //false 从第10位开始没有包含 Laravist

4.repeat(次数) 重复多少次
'哈'.repeat(3) // '哈哈哈'


对象解构
帮助我们能快速的从对象中 提取到我们所需要的属性 可以嵌套

const Tom = {
name: "tom jones"
age: 25
family: {
mother: "norah"
father: "richard"
brother: "howard"
}
}

const {name,age} = Tom
console.log(name)
console.log(age)

//(father: f)是重新命名 声明了f变量 cat = details 设置默认值 但必须是undifande才能设置 不是undifande会使用变量指定的值
const {father: f,brother,cat = 'have cat'} = Tom.family
console.log(f)
console.log(brother)
console.log(cat)

数组解构

const numbers = ['one','two','three','four']
let a = 10
let b = 20

const [one,two] = numbers
const [one,,three] = numbers //获取0和2位置的两个变量值
const [one, ...others] = numbers //获取0和后面所有的变量值
const [one,two = ‘PHP’] = numbers //设置默认值 但必须是undifande才能设置
[a,b] = [b,a] //对象的值交换


for of循环遍历

数组 字符串 map set arguments nodelist...等等的数据结构 不支持对象
相对于for循环较简单 相对于for in循环 每次循环的是属性值 相对于forEach 这个是支持 终止和跳过 循环
不会遍历数组上的非数值属性 如function

const fruits = ['apple','Banana','Orange','Mango']

for (let fruit of fruits) {
console.log(fruit)
}

.entries() 同时获取索引和值 这里使用了结构的方法

for (let [index,fruit] of fruits.entries()) {
console.log(${fruit} ranks ${index + 1} in my favorite fruits)
}

for of 用于所有参数之和

function sum(){
let total = 0
for(let num of arguments){
tatal = tatal + num
}
return total
}
sum (10,23,324,435,34,12)

for of 用于字符串
let name = 'Laravist'
for(let char of name){
console.log(char)
}


ES6新增数组函数方法

//常用于dom元素的操作 对函数arguments的操作 字符串map数据类型
Array.from('类数组对象',参数2相当于map方法) 把 类数组对象 或是 可遍历的对象 转换成一个真正的数组

//弥补了Array这个构造函数的不足 不管你传入多少参数 返回的都是这些参数组成的数组
Array.of() 保证返回结果的一致性 肯定返回数组 传入1 是1的数组 传入(1,2)是两个值的数组

.find() 查找 接受一个函数作为参数 函数参数:element,index,array
const inventory = [
{name: 'apples', quantity:2},
{name: 'banans', quantity:0},
{name: 'cherries', quantity:5}
]

const bananas = inventory.find(fruit => fruit.name === 'banans')
得到 {name: 'banans', quantity:0}

.findIndex() 查找下标
const bananas = inventory.findIndex(fruit => fruit.name === 'banans')
得到 下标 1

.some() 满足一个直接返回 接收函数作为参数 返回布尔值
const isEnough = inventory.some(fruit => fruit.quantity > 0)
得到 true 这里第一个apples 是满足的就直接返回了

.every() 满足所有返回 接收函数作为参数 返回布尔值
const isEnough = inventory.some(fruit => fruit.quantity > 0)
得到false 不是所有的参数都是满足的 第二个是0所以是false


剩余参数
1:
function sum(...numbers){
return numbers.reduce((prev,curr) => prev + curr,0)
}

console.log(sum(1,2,3,4)) 得到10

2:用于参数
function sum(rate,...numbers){
return numbers.map(number => number * rate)
}

const smounts = sum(0.89,12,34,658,23)
console.log(amounts)

3:用于变量结构
const player = ['jelly',123,5.4,6.7,3.4,7.8,8.9]

const [name,id,...numbers] = player

扩展运算符
可用于数组 dom 对象属性 对数组删除 得到一个新数组

const youngers = ['George','john','Thomas']
const olders = ['james','Adrew','Martin']

const members = [...youngers,'Mary',...olders] //这里扩展

const curren = [...members] //这里复制了members数组 赋值给curren
curren[0] = 'jelly' //这里修改了下标0的值 但是原数组members的George并没有修改

用于函数
const fruit = ['apple','bananas','pear']
const newFruit = ['orange','mongo']

fruit.push(...newFruit)
console.log(fruit) 得到 fruit = ['apple','bananas','pear','orange','mongo']

时间函数
const dateFields = [2017,5,6]
const date = new Date(...dateFields)

对象字面量的扩展 属性 方法简写
当对象数组扩展指的是同一个变量名字的时候 不用重复的写name:name了
函数方法可以不用重复写 :function
const name = 'Laravist'
const age = 2
const birthday = '2015-09'

const Larvist = {
name,
age,
birthday,
greet(){
console.log(hello${this.name})
}
}

用于计算属性简写
let id = 0

const userIds = {
[user-${++id}],
[user-${++id}],
[user-${++id}]
}

得到 {user-1:1,user-2:2,user-3:3}

const keys = ['name','age','birthday']
const values = ['Laravist',2,'2015-09']

const Larvist = {
[keys.shift()]: values.shift(),
[keys.shift()]: values.shift(),
[keys.shift()]: values.shift(),
}

得到 {name:'Laravist',age: 2,birthday: '2015-09'}


Promise 解决回调地狱
axios 包支持promiseAPI 帮助我们发起ajax请求 引入包后
异步编程的反馈 一个承诺 通常用于调用api 或 json数据 或ajax请求当中
当你需要某些操作 并且只需要知道它的操作结果 再进行其他事情 而不用暂停等待的时候 就可以使用Promise

{
let username
const usersPromise = axios.get('http://api.github.com/users') //返回一个promise 代表promise收到了 给你一个回应

usersPromise.then(reponse => { //then相当于事件的on 当这件事then的时候 做一个什么事
username = reponse.data[0].login
return axios.get('http://api.github.com/users${username}/repos')
}).then(reponse => {
console.log(reponse)
}).catch(err => { //这里.catch 是当发生错误时 怎么处理 做什么事
console.error(err)
})
}

自己编写一个Promise

//创建一个Promise构造函数 参数是一个函数 然后函数有两个内置参数1.resolve,2.reject
如果这个Promise是成功的 返回reslove 里传入成功的数据 失败调用reject返回失败的信息

const p = new Promise((resolve,reject) => {
reslove('Laravist is awesome')
setTimeout(() => {
{
reject(Error('Laravist isn 't awesome!')) //Error指明错误是出现在这一行
}
},2000)
})

p.then(data => {console.log(data)})
.catch(err => {console.error(err)})

.get('http://'); ajax请求
Promise.then 处理回调地狱 相当于事件监听
Promise.catch(err => {console.error(err)}) 监听处理错误 如果没写发生错误就不会告诉你发生错误 只有写了才有
Promise.all([]) 当多个promise完成之后 就返回对应的一个结果 结果的数组 是和自己传入的数组 的顺序是一样的 要都是resolve 才会执行then 如果有一个结果是reject 就执行catch
Promise.race([]) 由第一个返回的promise状态决定 如果是resolve 执行then 如果是reject 执行catch


symbol 数据类型 唯一标识符 解决了对象命名冲突问题
不能遍历 可以作为私有属性在对象内部使用

const prter = Symbol('prter') //创建一个symbol对象
const student = Symbol('student') //
prter === student 得到false

cosnt classRoom = {
[symbol('lily')]: {grade: 60, gender: 'female'}
[symbol('nina')]: {grade: 80, gender: 'female'}
[symbol('nina')]: {grade: 90, gender: 'female'}
}

可以通过这个方法遍历
const syms = Object.getOwnPropertySymbols(classRomm).map(sym => clasRomm[sym]);


ESlint
可组装的javaScript和jsx检查工具
安装 npm install eslint
生成配置文件 eslint --init 配置文件运行环境: 浏览器 'browser': true; 'es6': true; 'commonjs': true
使用检查命令 eslint xxx.js
自动修复一些问题 eslint xxx.js --fix
使用eslint推荐规则 'extends': 'eslint:recommended'
自己配置的一些规则写在 'rules'里
找不到Vue 'globals':{'Vue': true}
更多的使用 : http://github.com/airbnb/javascript 这个书写规则


导入导出 模块
模块化可以把一些如函数处理逻辑放到一个文件里 用模块导出的方式 供其他文件导入使用相关处理函数来处理数据
可以使代码更干净舒适 有利于测试代码

npm init 生成packge文件

import moment from 'moment' 默认导入
import { uniq } from 'lodash'命名导入 必须当时模块的名字 还需要加{} 可以多个导出

export { key} 命名导出
export default xxx 默认导出 一个模块只能有一个默认导出

生成自己的模块

次文件里:
const apikey = 'abc123'
export default apikey //命名导出 或者 export const apikey = 'abc123' 这是命名导出

主文件里:
import apikey(这个名字可以自写) from './config' //路径导入
console.log(apikey)

as 可以改导入或者导出的内容重新命名如:
export {apikey as key, age, greet}
import { uniq as apikey } from 'lodash'
导出导入都可以用as来重命名//导出重命名修改后 要导入时是导入as后的变量模块名

使用SustemJS 打包es6 模块
用于简单测试 或者是写一点小东西的话 是非常有用的


Babel
把es6代码转换成es5代码

初始化packge文件 npm init
安装 npm install babel-cli --save-dev
因为并不是全局安装的 所以不能在命令行直接使用 所以要在packge文件里的scrits语句
在packge文件里 添加转换es5规则集:
'babel':{
'presets': ['es2015']
}

polyfill
es6一些新增属性的补充转换 如from方法 set map方法等... babel的补充转换
最新版本的chrome浏览器 不需要polyfill
常用两个polyfill :
1、babel的
2、polyfill.io 去百度搜 引入script标签就行



实现原形继承
class是一个函数 但是没有函数提升 不能在写在调用后面 只能通过new来调用

两种方法
1、类的声明
class User {

}

2、类的表达式
const User = class 名字可选 {

}

constructor 等于之前写的构造函数 //function User(name,email){this.name = name; this.email = email}
class里的 info等于之前的 //User.potrotype.info = function(){} 没有逗号

类的静态方法: static 关键字 只能自己User用 static description () {console.log(I m a user of codecasts.com)}
User.description 得到 I m a user of codecasts.com

set 关键字方法使用:
codecasts.github = 'Larvist' 得到Larvist

get 关键字方法使用:
codecasts.github 得到 https://github.com/Larvist

方法info 也可以使用计算属性的方法来定义 let methodName = 'info' class里 [methodName] 代替info

class User(){
constructor(name,email){
this.name = name
this.email = email

}

info(){
 console.log(`Hi,Im${this.name},my email is ${this.email}`)

}

static descroption(){
  console.log(`I m a user of codecasts.com`)

}

set github(value){
 this.githubName = value

}

get github(){
  return `https://github.com/${this.githubName}`

}
}

const p = new User('codecasts','[email protected]')


类class继承

extends 类的继承 这里Dog 继承了 Animal

{
子类里面用super()来获取基类 this指向Animal name是传入基类需要的name参数
相等于es5:
function(){
Animal.call(this,name,age)
this.name = name
this.age = age
}
Dog.prototype = new Animal()
Dog.prototype = Dog
}

子类的方法和基类相同的话 会覆盖基类的方法

class Animal{
constructor(name){
this.name = name;
this.belly = [];
}
eat(food){
this.belly.push(food)
}
}

class Dog extends Animal {
constructor(name,age){
super(name)
this.age = age
}

bark(){
 console.log(`Barl bark`)

}
}

const lucky = new Dog('lucky,2')


class扩展内建对象数组

class MyArray extends Array {
constructor(){
super()
}
}

const colors = new MyArray()
colors[0] = 'red'
console.log(colors.length); 得到 1 因为有一个red

colors.length = 0
console.log(colors.length); 得到 undefined 因为 设置为0了
0


lterator 遍历器

遍历器就是有一个对象 这个对象有一个next()方法 会返回给我们所需要的数据
可遍历对象是部署了 Symbol.iterator 属性的对象 这个 Symbol.iterator 会返回给我们一个 遍历器
然后每次调用这个遍历对象的时候 就会返回给我们相应的值

const colors = ['red','blue','green']
const iterator = colorsSymbol.iterator
console.log(iterator) 返回一个 Array Iterator{}对象 里面有一个next()方法

调用一次
iterator.next() 返回一个对象 有两个属性 {value:'red',done:false}
再调用一次
iterator.next() 返回一个对象 有两个属性 {value:'blue',done:false}
再调用一次
iterator.next() 返回一个对象 有两个属性 {value:'green',done:false}
再调用一次
iterator.next() 返回一个对象 有两个属性 {value:undefined,done:true}

ES6当中有三种类型的集合对象
1.Arrey
2.map [es6]
3.set [es6]
es6为这三种类型 内建了遍历器 可以通过调用相应的方法来获取它们 如:

对于数组
const iterator = colors.entries() //entries()返回元素的 属性名 和 属性值
const iterator = colors.keys() // 返回元素的索引值
const iterator = colors.values() // 返回元素的值
调用一次
iterator.next() 返回一个数组 {value: Array(2),done:false} //Array(2)里是 0:0下标 1:'red'值
调用一次
iterator.next() 返回一个数组 {value: Array(2),done:false} //Array(2)里是 0:1下标 1:'blue'值
调用一次
iterator.next() 返回一个数组 {value: Array(2),done:false} //Array(2)里是 0:2下标 1:'green'值
调用一次
iterator.next() 返回一个数组 {value: undefined,done:false}


Generator 生成器

生成器是能返回一个迭代器的函数
yield 相当于 return 但是只是trturn本次执行函数的返回值
调用colors的时候不会执行 生成器函数 function* 只有调用colors.next() 才会调用 生成器函数function*

定义
function* Colors(){
yield 'red'
yield 'green'
yield 'blue'

let i = 0
yield i
i++
yield i
i++
yield i

}

实例
const colors = Colors();

执行调用
colors.next() 得到{value: 'red', done: false}


Generator应用
如控制ajax的工作流

function ajax(url){
axios.get(url).then(res => userGen.next(res.data))
}

function* steps(){
const users = yield ajax('https://api.github.com/users')
const firstUser = yield ajax('https://api.github.com/users/${users[0].login}')
const followers = yield ajax(firstUser.followers_url)
}

const userGen = steps()
userGen.next()


Proxy
能够帮助我们 重写 一些对象默认方法 赋予我们自定义的逻辑方法

const person = {name:'laravist', age: 2000}
const personProxy = new Proxy(person,{
get(target,key){
return target[key].toUpperCase()
},
set(target,key,value){
if(typeof value === 'string'){
target[key] = value.trim()
}
}
})

personProxy.name = 'codecasts'
personProxy.love = ' i love codecasts '
personProxy.love 得到 'I LOVE CODECASTS'


set 数组集合类型
唯一的数组 元素不会有重复的存在 重复时会忽略
数字1 和字符串'1' 在set里是两个元素
不能通过索引值来获取元素[0]
可以遍历for of forEach next

实例
const colors = new Set(['black']);

调用
colors.add('red')
colors.add('green')
colors.add('blue')
得到 {'red','green','blue'}

colors.size //获取set数组的长度
得到 //3

colors.delete("red") //删除元素
得到 //true colors里red就删除了

colors.has('5') //检查这个元素是否存在
得到 //true

colors.clear() //清空所有元素
把这个数组的元素给清空了

Set去重 转换成数组
const numbers = [1,2,3,4,5,5,5,5,5,5]

const numbersSet = new Set(numbers)

const uniqueNumbers = [...numbersSet]


WeakSet

WeakSet的元素只能是对象
不能for of forEach .size .clear
会有自动清除机制

let jelly = {name: 'jelly',age:'20'}
let mary = {name: 'mary ',age:'25'}

const weakPeple = new weakSet([jelly,mary])

consolo.log(weakPeple)
mary = null //这里删除了mary
consolo.log(weakPeple) //但是普通数组方法这里还是会打印出来 就是[内存泄露] 所以用WeakSet

使用情况:
属性只能是对象的时候
数据不可用之后 希望集合当中的 相关的 引用和数据会被自动回收 以达到一个内存优化的目的


Map 键值对集合类型
键(key)可以是任意类型的数据比如对象{},3 属性可以是任意类型的数据
可以遍历 for of forEach
唯一的对象 元素不会有重复的存在 重复时会忽略

const people = new Map([['apple,',6],['banana',5]]) //数组中 的相对应 数组

people.set('jelly',23)
people.set('mary',25)
people.set('miffy',30) //添加新的元素
得到// {'jelly':23,'mary':25,'miffy':30}

people.get('jelly') //输入key获得相对应的value
得到 // 23

people.size //获取键(key)值(value)对的数量
得到// 3

people..has('jelly') 检查这个属性是否存在
得到// true

people.delete("mary") 删除元素
得到// true 数组相应键值对删除

people.clear 清空所有元素
得到//清空所有元素键值对的对象

使用情况:
当你想要存储关于这个对象的信息 而不是把这个信息存储在这个对象上的时候 使用map来操作


WeakMap
WeakMap的key只能是对象
不能for of forEach .size .clear
会有自动清除功能 如果这个对象在其他地方没有引用的话 就会自动清除

let jelly = {name: 'jelly'}
let miffy = {name: 'miffy'}

const weak = new WeakMap()

weak.set(miffy,'miffy is the 2nd best!')
jelly = null
miffy = null

使用情况:
属性只能是对象的时候
数据不可用之后 希望集合当中的 相关的 引用和数据会被自动回收 以达到一个内存优化的目的

你可能感兴趣的:(ES6)