ES6学习

let && const

let定义变量,const定义常量

  • 不存在变量提升
  • 暂时性死区
  • 不允许重复声明
  • 块级作用域
  • 不属于顶层对象window
  • const:值不得改变,一旦声明,必须立即初始化
  • const:本质
不存在变量提升
// var
console.log(a)
// 变量提升
var a = 5

// 相当于
var a
console.log(a)
a = 5

在这里插入图片描述

// let
console.log(a)
let a = 5

在这里插入图片描述

暂时性死区
var temp = 123
if (true) {
  temp='abc'
  let temp
}

在这里插入图片描述

虽然声明了全局变量tmp,但是块级作用域只要let命令,它声明的变量就会绑定到这个区域,所以tmp是声明之前赋值就会报错

不允许重复声明
// var允许重复定义,后定义的会覆盖掉先定义的
var a=5
var a=6
console.log(a)

在这里插入图片描述

// let 不允许重复定义
let a=5
let a=6
console.log(a)

在这里插入图片描述

块级作用域
问题1:内层变量可能覆盖外层变量
// var
function f1() {
  var n = 5
  if (true) {
    var n = 10
  }
  console.log(n)
}
f1()

在这里插入图片描述

// let
function f1() {
  let n = 5
  if (true) {
    let n = 10
  }
  console.log(n)
}
f1()

在这里插入图片描述

问题2:用来计数循环的变量泄露为全局变量
// var
for(var i=0; i<3; i++) {
  // 
}
console.log(i) // 3

在这里插入图片描述

// let
for(let i=0; i<3; i++) {
  // 
}
console.log(i) // 3

在这里插入图片描述

不属于顶层对象window
// var
var a = 5;
console.log(a)
console.log(window.a)

在这里插入图片描述

//let
let a = 5
console.log(a)
console.log(window.a)

在这里插入图片描述

let避免污染全局变量

const:一旦声明,必须立即初始化
const c
c = 9

在这里插入图片描述

const:本质

const实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。对于简单类型的数据(数值、字符串、布尔值)而言,值就保存在变量指向的内存地址中,因此等同于常量。但对于复合类型的数据(主要是对象和数组)而言,变量指向的内存地址保存的只是一个指针,const只能保证这个指针是固定的。

// 对象
const foo = {}
foo.prop = 123
// 添加属性,可以
console.log(foo)
// 指向另一个对象,报错
foo = {}

在这里插入图片描述

// 数组
const a = []
// 可以
a.push('bianyu')
console.log(a)
// 可以
a.length = 0
console.log(a)
// 报错
a = ['test']

在这里插入图片描述

若是想将对象冻结,用Object.freeze

const foo = Object.freeze({})
foo.props = 123
console.log(foo)

在这里插入图片描述

解构赋值

按照一定模式(两侧结构相同),从数组和对象中提取值,对变量进行赋值

数组结构
let arr = [1, 2, 3]

let a = arr[0]
let b = arr[1]
let c = arr[2]

// 等价的
let [a, b, c] = arr

console.log(a, b, c)

在这里插入图片描述

// 二维数组
let [a, b, [c, d]] = [1, 2, [3, 4]]
console.log(a, b, c, d)

在这里插入图片描述

let [a, b, [c]] = [1, 2, [3, 4]]
console.log(a, b, c)

在这里插入图片描述

let [a, b, c] = [1, 2, [3, 4]]
console.log(a, b, c)

在这里插入图片描述

// d为undefined,相当于定义了一个d,没有给它初始值
let [a, b, c, d] = [1, 2, [3, 4]]
console.log(a, b, c, d)

在这里插入图片描述

let [a, b, c, d=5] = [1, 2, [3, 4], 6]
console.log(a, b, c, d)

在这里插入图片描述

对象解构
let user = {
  name: 'bian',
  age: 18
}

let name = user.name
let age = user.age
// 等价
let {name, age} = user
console.log(name, age)

在这里插入图片描述

let user = {
  name: 'bian',
  age: 18
}

// 令起一个名字
let {age: uage, name: uname} = user
console.log(uage, uname)

在这里插入图片描述

字符串
let str = 'es6learn'
for (let i=0;i<str.length;i++) {
  console.log(str[i])
}

// 理解为数组的解构
let [a, b, c, d, e, f, g, h] = str
console.log(a, b, c, d, e, f, g ,h)

在这里插入图片描述

数组的遍历方式

es5中
  • for循环
  • forEach(): 没有返回值,只针对每个元素调用函数
  • map(): 返回新的数组,每个元素为调用函数的结果
  • filter(): 返回符合函数条件的元素数组
  • some(): 返回布尔值,判断是否有满足函数条件的元素
  • ervey(): 返回布尔值,判断每个元素是否满足函数条件
  • reduce(): 接受一个函数作为累加器
  • for in
let arr = [1, 2, 3]
for(let i = 0; i< arr.length; i++) {
  console.log(arr[i])
}
// 等同
arr.forEach((item) => {
  console.log(item)
})

在这里插入图片描述

forEach无法跳出循环,即无法使用break和continue

let arr = [1, 2, 3]
let result = arr.map((item) => {
  item += 1
  return item
})
console.log(arr, result)

在这里插入图片描述

返回新数组,不改变原有数组

let arr = [1, 2, 3]
let result = arr.filter((item) => {
  return item%2!==0
})
console.log(arr, result)

在这里插入图片描述

返回新数组,不改变原有数组

let arr = [1, 2, 3]
let result = arr.some((item) => {
  return item%4===0
})
console.log(arr, result)

在这里插入图片描述

返回布尔值,不改变原数组

let arr = [1, 2, 3]
let result = arr.every((item) => {
  return item%2===0
})
console.log(arr, result)

在这里插入图片描述

返回布尔值,不改变原数组

let arr = [1, 2,2,3, 3]

// 累加
let result = arr.reduce((prev, cur, index, arr)=> {
  return prev + cur
}, 0,)
console.log(result)

在这里插入图片描述

let arr = [1,3,5,6,6]
Array.prototype.foo = ()=>{
  console.log('foo')
}
for(let i in arr) {
  console.log(arr[i])
}

在这里插入图片描述

for in 在遍历数组时存在问题,不可取

es6中
find

返回第一个通过测试的元素

let arr = [1,3,5,6,6]
let result = arr.find((item)=>{
  return item === 6
})
console.log(arr, result)

在这里插入图片描述

findIndex

第一次出现元素的索引

let arr = [1,3,5,6,6]
let result = arr.findIndex((item)=>{
  return item === 5
})
console.log(arr, result)

在这里插入图片描述

for of
let arr = [1,3,5,6,6]
Array.prototype.foo = ()=>{
  console.log('foo')
}
for(let item of arr) {
  console.log(item)
}

在这里插入图片描述

数组的扩展

类数组/伪数组
let divs = document.getElementsByTagName('div')
console.log(divs) // HTMLCollection
console.log(divs instanceof Array) //false

let classes = document.getElementsByClassName('div')
console.log(classes) // HTMLCollection
console.log(classes instanceof Array) //false

let query = document.querySelectorAll('div')
console.log(query) // NodeList
console.log(query instanceof Array) //false

query.push(123) // 报错

在这里插入图片描述

function foo () {
  console.log(arguments)
  console.log(arguments instanceof Array)
}
foo(2, 'test', true)

在这里插入图片描述

并不是真正意义上的数组,是一个含有length属性的json对象,它是按照索引的方式存储数据,它并不具有数组的一些方法。

Array.from

将类数组转化为数组

let arrLike = {
  0: '0',
  1: '1',
  2: '2',
  length: 3
}
let arr = Array.from(arrLike)
console.log(arr)
console.log(arr[1])

在这里插入图片描述

Array.of

将一组值转化为数组

let arr1 = new Array(1,2)
console.log(arr1)
let arr2 = new Array(3)
console.log(arr2)

在这里插入图片描述

传1个参数代表数组的长度,1个以上为数组的参数,行为不统一

let arr1 = Array.of(1,2)
console.log(arr1)
let arr2 = Array.of(3)
console.log(arr2)

在这里插入图片描述

// 拼装新数组
let arr = Array.of(1, true, 'test', [1,3], {name: 'bian '})
console.log(arr)

在这里插入图片描述

copyWithin

在当前数组内部将指定位置的成员复制到其他位置(会覆盖原有成员)
接收3个参数

  • target(必选):从该位置开始替换
  • start(可选):从该位置开始读取,默认0,负值表示倒数
  • end(可选):到该位置前停止读取,默认为数组的长度,负值表示倒数
let arr = [1, 2, 3, 4, 5]
let arr1 = [1,2,3,4,5].copyWithin(0,3)
console.log(arr1)
let arr2 = [1,2,3,4,5].copyWithin(0,3,4)
console.log(arr2)
let arr3 = [1,2,3,4,5].copyWithin(0,-2,-1)
console.log(arr3)

在这里插入图片描述

fill

用给定值填充一个数组
3个参数,填充的数值,起始位置,结束位置

let arr1 = ['a','b','c'].fill(7)
console.log(arr1)
let arr2 = new Array(3).fill(7)
console.log(arr2)
let arr3 = ['a','b','c'].fill(7,1,2)
console.log(arr3)

在这里插入图片描述

includes

用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。

let arr = [1, 3, 3, NaN]
console.log(arr.indexOf(NaN))
console.log(arr.includes(NaN))

在这里插入图片描述

es5的indexOf不可判断NAN,includes可以

函数

参数的默认值
// 可传默认值
function foo(x, y='world') {
  console.log(x, y)
}
foo ('hello')

在这里插入图片描述

// 默认声明,不可重复声明
function foo(x=5) {
  let x = 1
}
foo()

在这里插入图片描述

function foo(x, y=5, z) {
  console.log(x, y, z)
}
foo(1,4)

function foo(x, z, y=5) {
  console.log(x, y, z) // 1 5 4
}
foo(1,4)

在这里插入图片描述

带默认值的参数放在所有参数的后面

与解构赋值的结合
function foo ({x,y=5}) {
  console.log(x,y)
}

foo({})
foo({x: 1})
foo({x:1,y:3})
foo()

在这里插入图片描述

两侧的结构必须对应

length属性
function foo(x, y=1,z=3) {
  console.log(x, y)
}
// 没有指定默认值的此参数的个数
console.log(foo.length)

在这里插入图片描述

作用域
// 参数一旦设置默认值,就会形成一个单独的作用域
let x = 1
function foo(x, y = x) {
  console.log(y)
}
foo(2)

在这里插入图片描述

let x = 1
// 当前作用域找不到,向上级作用域查找
function foo(y = x) {
  let x = 2
  console.log(y)
}
foo()

在这里插入图片描述

rest参数

把用逗号分割的项组成一个数组

function foo (...args) {
  console.log(args)
}

foo(1,2)
foo(1,2,3)

在这里插入图片描述

function foo (x, ...args) {
  console.log(x, args)
}

foo(1, 2,3)

在这里插入图片描述

箭头函数
  • this指向定义时所在的对象,而不是调用时所在的对象
  • 不可以当构造函数
  • 不可以使用arguments对象
// 左边是参数,右边是函数体
let sum = (x, y) => {
  return x+y
}
// 只有一行代码,可以简写
let sum = (x, y) => x+y
console.log(sum(2,4))
let oBtn = document.querySelector('#btn')
oBtn.addEventListener('click', function(){
  setTimeout(function(){
    console.log(this)
  }, 1000)
})

在这里插入图片描述

this指向调用时的对象

let oBtn = document.querySelector('#btn')
oBtn.addEventListener('click', function(){
  setTimeout(() => {
    console.log(this)
  }, 1000)
})

在这里插入图片描述

箭头函数指向定义时的对象

let People = (name, age) => {
  this.name = name
  this.age = age
}
let p1 = new People('bian', 18)
console.log(p1)

在这里插入图片描述

不可以当构造函数

let foo = () => {
  console.log(arguments)
}

foo(1, 3, 4)

在这里插入图片描述

不可以使用arguments对象

对象的扩展

属性简洁表示法
let name = 'bian'
let age = 18

let obj = {
  name,
  age
}
console.log(obj)

在这里插入图片描述

键值相等可简写

属性名的表达式
let name = 'bian'
let age = 18
let s = 'job'

let obj = {
  name,
  age,
  [s]: 'font'
}
console.log(obj)

在这里插入图片描述

[]代表key值为变量

Object.is

判断两个的值是否严格相等

console.log(Object.is(2, '2'))
console.log(Object.is(NaN, NaN))
console.log(Object.is(+0, -0))
let obj1 = {
  name: 'bian',
  age: 18
}
let obj2 = {
  name: 'bian',
  age: 18
}
console.log(Object.is(obj1, obj2))

在这里插入图片描述

Object.assign()

用于合并对象,后面的会覆盖前面的

let x = {
  a: 3,
  b: 4
}
let y = {
  c: 5,
  a: 6
}
Object.assign(y, x)
console.log(y)

在这里插入图片描述

in

判断当对象中是否包含某个属性

let y = {
  c: 5,
  a: 6
}
console.log('a' in y, 'd' in y)

在这里插入图片描述

对象的遍历
let obj = {
  name: 'bian', 
  age: 18,
  job: 'font'
}

for(let key in obj) {
  console.log(key, obj[key])
}
console.log('--')
Object.keys(obj).forEach(key => {
  console.log(key, obj[key])
})
console.log('--')
Object.getOwnPropertyNames(obj).forEach(key => {
  console.log(key, obj[key])
})
console.log('--')
Object.ownKeys(obj).forEach(key => {
  console.log(key, obj[key])
})

在这里插入图片描述

深拷贝与浅拷贝

let target = {
  a: {
    b: {
      c: 1
    },
    e: 4,
    f: 5,
    g: 6
  }
}
let source = {
  a: {
    b: {
      c: 1
    },
    e: 2,
    f: 3
  }
}
Object.assign(target, source)
console.log(target) // g丢失

在这里插入图片描述

用Object.assing去赋值一个比较复杂的结构时并不安全,只是浅拷贝

let obj1 = {
  name: 'bian',
  age: 18
}
let obj2 = obj1
obj1.age = 16
console.log(obj1, obj2)

在这里插入图片描述

相当于obj1和obj2指向了同一块内存地址,浅拷贝

let obj1 = {
  name: 'bian',
  age: 18
}

let obj2 = JSON.parse(JSON.stringify(obj1))
obj1.age=16
console.log(obj1, obj2)

在这里插入图片描述

JSON.parse(JSON.stringify())对象里的方法不能拷贝

类与继承

// 类
class People {
  // 构造函数
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  showName() {
    console.log(this.name)
  }
}
let p1 = new People('bian', 18)
console.log(p1)
p1.showName()

在这里插入图片描述

// 继承
class Coder extends People {
  constructor(name, age, company) {
    // 继承当前父类的属性
    super(name, age)
    this.company = company
  }
  showCompany() {
    console.log(this.company)
  }
}

let c1 = new Coder('yu', 26, 'cmss')
console.log(c1)
c1.showName()
c1.showCompany()

在这里插入图片描述

// 类
class People {
  // 构造函数
  constructor(name, age) {
    this.name = name
    this.age = age
    this._sex = 'female'
  }
  get sex() {
    return this._sex
  }
  set sex(val) {
    this._sex = val
  }
}
let p1 = new People('bian', 18)
console.log(p1.sex)
p1.sex = 'male'
console.log(p1.sex)

在这里插入图片描述

在类的顶层定义属性的时候要用get和set,里面可以写一些业务逻辑

// 类
class People {
  // 构造函数
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  // 静态方法,不能被实例调用,子类可以调用
  static getCount() {
    return 5
  }
}
let p1 = new People('bian', 18)
console.log(People.getCount())
// class不支持静态属性的定义,可以定义在class外部
People.count = 9
console.log(People.count)

在这里插入图片描述

Symbol

新的原始数据类型(symbol、undefined、null、sring、boolean、number、object),代表唯一标识

let s1 = Symbol()
let s2 = Symbol()

console.log(s1)
console.log(s2)
console.log(s1===s2)

在这里插入图片描述

// for,相当于定义在全局的环境
let s1 = Symbol.for('foo')
console.log(s1)
let s2 = Symbol.for('foo')
console.log(s2)

console.log(s1 === s2)

在这里插入图片描述

不会每次调用就返回一个新的Symbol类型的值,而是会先检查给定的key值是否已经存在,不存在的话才会新建一个值

let s1 = Symbol('foo')
console.log(Symbol.keyFor(s1))

// 返回已经登记的全局的
const s2 = Symbol.for('foo')
console.log(Symbol.keyFor(s2))

在这里插入图片描述

const grade = {
  张三: {address: '1', tel: '2'},
  李四: {address: '2', tel: '2'},
  李四: {address: '3', tel: '3'}
}
console.log(grade)

在这里插入图片描述

对象中key必须是唯一的,后定义的会覆盖先定义的

const stu1 = Symbol('李四')
const stu2 = Symbol('李四')

const grade = {
  张三: {address: '1', tel: '2'},
  [stu1]: {address: '2', tel: '2'},
  [stu2]: {address: '3', tel: '3'}
}
console.log(grade)

在这里插入图片描述

把Symbol作为当前对象的key,保证key不冲突

// const shapeType = {
//   triangle: 'Triangle',
//   circle: 'Circle'
// }
const shapeType = {
  triangle: Symbol(),
  circle: Symbol()
}

// 消除魔术字符串
function getArea(shape) {
  let area = 0
  switch(shape) {
    case shapeType.triangle:
      area = 1
      break
    case shapeType.circle: 
      area = 2
      break
  }
  return area
}

console.log(getArea(shapeType.triangle))

在这里插入图片描述

Set

新的数据结构,其中不会有重复的值

let s = new Set([1, 2, 3, 3])
// 不可重复
console.log(s)
console.log('--')
// 添加可链式操作
s.add('1').add('2')
console.log(s)
console.log('--')
// 删除
s.delete(2)
console.log(s)
console.log('--')
// 判断是否有值
console.log(s.has('1'))
console.log(s.has(5))
console.log('--')
// set大小
console.log(s.size)
console.log('--')
// set循环遍历key和value是相等的
for(let i of s.entries()) {
  console.log(i[0], i[1])
}
console.log('--')
// 清空
s.clear()
console.log(s)

在这里插入图片描述

// 数组去重
let arr = [1,3,3,4,5,5]
let s = new Set(arr)
console.log(s)

在这里插入图片描述

// 合并去重
let arr1 = [1,2,3,4]
let arr2 = [2,3,4,5,6]
let s = new Set([...arr1, ...arr2])
console.log([...s])
console.log(Array.from(s))

在这里插入图片描述

Map

键值对的形式,他的key不仅限于字符串

let m = new Map()
let obj = {
  name: 'bian'
}
// 设置值
m.set(obj, 'test')
console.log(m)
console.log('--')
// 获取值
console.log(m.get(obj))
console.log('--')
// 是否有值
console.log(m.has(obj))
console.log('--')
// 大小
console.log(m.size)
console.log('--')
// 删除值
m.delete(obj)
console.log(m)
console.log('--')

在这里插入图片描述

字符串扩展

字符串的遍历器接口
for (let i of 'test') {
  console.log(i)
}

在这里插入图片描述

模板字符串
// 字符串换行
const str = `test
test1
test2`
console.log(str)

在这里插入图片描述

// 逻辑运算拼接
const a =  20
const b = 14
const c = 'test'
const str = `${c}${a+b}`
console.log(str)

在这里插入图片描述

includes、startsWith、endsWith
const s = 'Hello World!'

console.log(s.startsWith('Hello'))
console.log(s.endsWith('!'))
console.log(s.includes('o'))

在这里插入图片描述

支持第二个参数,表示搜索的开始位置

repeat

字符串重复n次

console.log('x'.repeat(3))
console.log('hello'.repeat(2))

在这里插入图片描述

数值的扩展

二八进制
// es5
// 十 -> 二
const a = 5
console.log(a.toString(2))

// 二 -> 十
const b = 101
console.log(parseInt(b, 2))

// es6 0B二进制 0O八进制
const c = 0B0101
console.log(c)
const d = 0O777
console.log(d)

在这里插入图片描述

Number.isFinite()、Number.isNaN()

Number.isFinite()判断是否是有限的
Number.isNaN()判断是不是NaN

console.log(Number.isFinite(5))
console.log(Number.isFinite(Infinity))
// 非数字一律为false
console.log(Number.isFinite('test'))
console.log(Number.isFinite(true))

在这里插入图片描述

console.log(Number.isNaN(NaN))
console.log(Number.isNaN(15))

在这里插入图片描述

Number.parseInt()、Number.parseFloat()
console.log(Number.parseInt(5.5))
console.log(Number.parseFloat(5.5))

在这里插入图片描述

Number.isInteger()

判断是否为整数

console.log(Number.isInteger(5))
console.log(Number.isInteger(5.5))

在这里插入图片描述

Math.trunc()

去除小数部分

console.log(Math.trunc(5.5))
console.log(Math.trunc(-5.5))

在这里插入图片描述

Math.sign

判断正数、负数、0

console.log(Math.sign(5))
console.log(Math.sign(-5))
console.log(Math.sign(0))
console.log(Math.sign(NaN))
console.log(Math.sign(true))
console.log(Math.sign(false))

在这里插入图片描述

Math.cbrt

计算立方根

console.log(Math.cbrt(8))
console.log(Math.cbrt(9))
console.log(Math.cbrt('test'))

在这里插入图片描述

Proxy

Proxy可以理解成在目标对象前架设一个‘拦截’层,外界对该对象的访问都必须先通过这层拦截,一次提供了一种机制可以对外界的访问进行过滤和改写。
Proxy接受两个参数,第一个参数是所要代理的目标对象,第二个参数是一个配置对象。

get

用于拦截某个属性的读取操作,get方法的两个参数分别表示目标对象和要访问的属性

let arr = [7, 8, 9]
arr = new Proxy(arr, {
  get(target, prop) {
    return prop in target ? target[prop]: 'error'
  }
})
console.log(arr[1])
console.log(arr[8])

在这里插入图片描述

set

用于拦截某个属性的赋值操作,set方法的三个参数分别表示目标对象和要访问的属性和要设置的值

let arr = []
arr = new Proxy(arr, {
  set(target, prop, val) {
    if (typeof val === 'number' || typeof val === 'string') {
      target[prop] = val
      return true
    } else {
      return false
    }
  }
})

arr.push(5)
arr.push('5')
console.log(arr[0],arr[1])

在这里插入图片描述

has

用来拦截HasProperty操作,has方法的两个参数分别表示目标对象和要访问的属性

let range = {
  start: 1, 
  end: 5
}

range = new Proxy(range, {
  has(target, prop) {
    return prop >= target.start && prop <= target.end
  }
})
console.log(2 in range)
console.log(9 in range)

在这里插入图片描述

ownKeys

拦截自身属性的读取操作,循环遍历的时候常用

// 私有属性不被外部取到
let userinfo = {
  username: 'bian', 
  age: '34',
  _password: '***'
}

for(let key in userinfo) {
  console.log(key)
}
console.log('---')
userinfo = new Proxy(userinfo, {
  ownKeys(target) {
    return Object.keys(target).filter(key => !key.startsWith('_'))
  }
})

for(let key in userinfo) {
  console.log(key)
}

在这里插入图片描述

deleteProperty

用于拦截delete操作,如果这个方法抛出错误或者返回false,当前属性无法被delete命令删除

let user =  {
  username: 'bian', 
  age: '18',
  _password: '***'
}

user = new Proxy(user, {
  deleteProperty(target, prop) {
    if (prop.startsWith('_')) {
      throw new Error('不可删除')
    } else {
      delete target[prop]
      return true
    }
  }
})
delete user.age
console.log(user)
delete user._password
console.log(user)

在这里插入图片描述

apply

拦截函数的调用,接收3个参数,分别是目标对象、目标对象的上下文对象、目标对象的参数数组

let sum = (...args) => {
  let num = 0
  args.forEach(item => {
    num += item
  })
  return num
}

sum = new Proxy(sum, {
  apply(target, ctx, args) {
    return target(...args) * 2
  }
})

console.log(sum(1,2))

在这里插入图片描述

contruct

拦截new命令,接收三个参数目标对象,构建函数的参数对象,new命令作用的构造函数

let User = class {
  constructor(name) {
    this.name = name
  }
}

User = new Proxy(User,  {
  construct(target, args, newTarget) {
    console.log('construct')
    return new target(...args)
  }
})

console.log(new User('test'))

在这里插入图片描述

Reflect

将Object属于语言内部的方法放到Reflect上

将Object对象的一些明显属于语言内部的方法(比如Object.defineProperty)放到Reflect对象上。现阶段,某些方法同时在Object和Reflect对象上部署,未来的新方法将只放在Reflect对象上部署。

let obj = {}
let newVal = ''
// 等价
Reflect.defineProperty(obj, 'name', {
// Object.defineProperty(obj, 'name', {
  get() {
    return newVal
  },
  set(val) {
    console.log('set')
    newVal = val
  }
})

obj.name = 'es'
console.log(obj.name)

在这里插入图片描述

修改某些Object方法的返回结果,让其便的合理
try {
  Object.defineProperty()
} catch(e) {

}

if (Reflect.defineProperty()) { // boolean

} else {
  
}
让Object操作变成函数行为
console.log('assign' in Object) // 命令式操作
console.log(Reflect.has(Object, 'assign'))

在这里插入图片描述

Reflect对象的方法与Proxy对象的方法一一对应
let user =  {
  username: 'bian', 
  age: '18',
  _password: '***'
}

user = new Proxy(user, {
  get(target, prop) {
    if(prop.startsWith('_')) {
      throw new Error('不可访问')
    } else {
      // return target[prop]
      return Reflect.get(target, prop)
    }
  },
  set (target, prop, val) {
    if (prop.startsWith('_')) {
      throw new Error('不可访问')
    } else {
      // target[prop] = val
      Reflect.set(target, prop, val)
      return true
    }
  },
  deleteProperty(target, prop) {
    if (prop.startsWith('_')) {
      throw new Error('不可删除')
    } else {
      Reflect.deleteProperty(target, prop)
      // delete target[prop]
      return true
    }
  }
})

Promise

// 基本用法
// resolve异步操作执行成功时的操作
// reject异步操作执行失败时的操作
let p = new Promise((resolve, reject) => {
  setTimeout(()=> {
    console.log('test')
    resolve('成功')
    // reject('失败')
  }, 1000)
}).then((res) => {
  console.log(res)
}, (res)=>{
  console.log(res)
})

在这里插入图片描述

let p = new Promise((resolve, reject) => {
  resolve(1)
  // pending->fullfilled ,不能再变成rejected
  reject(2)
})
p.then(res=>{
  console.log(res)
}).catch(err => {
  console.log(err)
})

在这里插入图片描述

三种状态,状态一旦改变就不可以再变,不可逆

// 解决回调地狱
function getPromise(url) {
  return new Promise((resolve, reject)=>{
    ajax(url, res => {
      resolve(res)
    })
  })
}
// 链式调用
// 代码扁平化
getPromise('a')
.then(res => {
  return getPromise('b')
}).then(res => {
  return getPromise('c')
}).then(res => {
  ...
})
Promise.resolve、Promise.reject

将现有的对象转为Promise

function foo(flag) {
  if(flag) {
    return new Promise(resolve => {
      resolve('success')
    })
  } else {
    return Promise.reject('fail')
  }
}

foo(false).then(res => {
  console.log(res)
}, err=>{
  console.log(err)
})

在这里插入图片描述

Promise.all、Promise.race
let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(1)
    resolve(1)
  }, 1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(2)
    resolve(2)
  }, 2000)
})

let p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(3)
    resolve(3)
  }, 3000)
})

// 三个异步操作完成之后,再去做接下来的操作
Promise.all([p1, p2, p3]).then(res => {
  // 三个都执行完,才执行这个
  console.log(res)
}, err => {
  console.log(err)
})

在这里插入图片描述

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(1)
    resolve(1)
  }, 1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(2)
    reject('2失败')
  }, 2000)
})

let p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(3)
    resolve(3)
  }, 3000)
})

// 三个异步操作完成之后,再去做接下来的操作
Promise.all([p1, p2, p3]).then(res => {
  // 三个都执行完,才执行这个
  console.log(res)
}, err => {
  console.log(err)
})

在这里插入图片描述

all,只要有一个失败的,就认为全部失败

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(1)
    resolve('1成功')
  }, 1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(2)
    resolve('2成功')
  }, 2000)
})

let p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(3)
    resolve('3成功')
  }, 3000)
})

Promise.race([p1, p2, p3]).then(res => {
  console.log(res)
}, err => {
  console.log(err)
})

在这里插入图片描述

只要有一个完成,就认为都完成

let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(1)
    reject('1失败')
    
  }, 1000)
})

let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(2)
    resolve('2成功')
  }, 2000)
})

let p3 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(3)
    resolve('3成功')
  }, 3000)
})

Promise.race([p1, p2, p3]).then(res => {
  console.log(res)
}, err => {
  console.log(err)
})

在这里插入图片描述

有一个失败就认为整个都失败

Generator

function* foo() {
  for(let i = 0; i< 3;i++) {
    console.log(i)
    yield i
  }
}

let f = foo()

console.log(f.next())
console.log(f.next())
console.log(f.next())
console.log(f.next())

在这里插入图片描述

g需要手动执行,不会立即执行,生成一个迭代器,调用迭代器的next的函数是,会执行yield后面为止

Iterator

让不支持遍历的结构“可遍历”

let languages = {
   allLanguage: {
     font: ['vue', 'js', 'html', 'reace'],
     back: ['java', 'python']
   }
}

for (let i of languages) {
  console.log(i)
}

在这里插入图片描述

// 可迭代协议,当前对象上要有Symbol.iterator属性
// 迭代器协议, 符合条件return {next(){return {value, done}}}
let languages = {
   allLanguage: {
     font: ['vue', 'js', 'html', 'react'],
     back: ['java', 'python']
   }
}

languages[Symbol.iterator] = function() {
  let allLanguage = this.allLanguage
  let keys = Reflect.ownKeys(allLanguage)
  let values = []
  return {
    next() {
      if (!values.length) {
        if(keys.length) {
          values = allLanguage[keys[0]]
          keys.shift()
        }
      }
      return {
        done: !values.length,
        value: values.shift()
      }
    }
  }
}

for(let i of languages) {
  console.log(i)
}

在这里插入图片描述

原生具备Iterator接口的数据结构

Array、
Map、
Set、
String、
TypedArray、
函数的arguments对象、
NodeList对象

Module

CommonJS: Node.js

仅仅局限于服务端

AMD:require.js

异步模块定义,在异步函数里面等待块加载完成,在回调函数里实现功能。依赖前置,提前执行

CMD:sea.js

依赖就近,延迟执行

ES6
export导入、import导入
// 一个文件中导出
const a = 5
const b = 'test'
const sum = (x, y) => {
  return x + y
}
const obj = {
  name: 'test'
}

class People {
  constructor(name) {
    this.name = name
  }
  showName() {
    console.log(this.name)
  }
}
export {a, b, sum, obj, People}

// 一个文件中导入
import {a, b, sum, obj, People} from './module'
console.log(a, b)
console.log(sum(1,2))
console.log(obj)
let p = new People('bian')
p.showName()

在这里插入图片描述

起别名 as
import {
  a as aa,
  b,
  sum as he,
  obj,
  People
} from './module'
export default
// 在一个文件中导出
const a = 5
export default a

// 在另一个文件中导入
import test from './module'
console.log(test)

导出文件:一个文件中只能有一个export default,导入文件可以自己定义导入的模块名

export 和 export default 混用
// 从一个文件中导出
function sum (x, y) {
  return x + y
}

export default sum

export const str = 'hahha'

// 在另一个文件中导入
import add, {str as haha} from './module'
console.log(add(1,2))
console.log(haha)
可以export defalut出文件中定义的所有值
// 从一个文件中导出
const a = 5
const b = 'test'
const sum = (x, y) => {
  return x + y
}
const obj = {
  name: 'test'
}

class People {
  constructor(name) {
    this.name = name
  }
  showName() {
    console.log(this.name)
  }
}


export default {
  a, b, sum, obj, People
}
// 第一种导入方法
import Test from './module'
console.log(Test)
console.log(Test.sum(1,2))

在这里插入图片描述

// 第二种导入方法
import * as Test from './module'
console.log(Test)
console.log(Test.default.sum(1,2))

在这里插入图片描述

async / await

让异步操作顺序执行,async写在function的前面,await在async里面,他俩成对出现。代码简洁,减少嵌套。

function timeout() {
  return new Promise(resolve => {
    setTimeout(()=>{
      console.log(1)
      resolve('test')
    }, 1000)
  })
}

async function foo() {
  // 相当于同步操作,要await后面的异步操作执行完毕才往下执行
  const res = await timeout()
  console.log(res)
  console.log(2) 
}
foo()

在这里插入图片描述

// reject的结果可以在catch中拿到
function timeout() {
  return new Promise((resolve, reject) => {
    setTimeout(()=>{
      reject('test')
    }, 1000)
  })
}

async function foo() {
  return await timeout()
}
foo().then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
})

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值