ECMAScript流水账

目录

作用域:最佳实践,不用var

解构

模板字符串

参数默认值,严格等于undefined

... 运算符

箭头函数,没有自己的this

Proxy

Reflect:(统一提供一套用于操作对象的方法)

Promise TODO

class 类 TODO 与 new Obj() 的区别

Set 数据结构:最常用来数组去重。。。。

Map 数据结构

Symbol

for ... of (iterable接口)

迭代器的意义:对外提供统一遍历接口

生成器 Generator

Esmodule TODO

ES2016

ES2017

async await TODO


  • 解决原有语法的一些问题或者不足
  • 对原有语法进行增强
  • 全新的对象,全新的方法,全新的功能
  • 全新的数据类型和数据结构

测试执行环境:nodejs 工具:nodemon

作用域:最佳实践,不用var

  • 局部作用域
  • 全局作用域
  • 块级作用域,let const。不影响其他作用域的变量,解决了变量提升的问题
var ele = [{},{},{}]
for(var i=0;i<3;i++){
  ele[i].onclick = function(){
    console.log(i)
  }
}

ele[0].onclick() // 此时打印的都是三

// 用闭包解决作用域的问题
var ele = [{},{},{}]
for(var i=0;i<3;i++){
  ele[i].onclick = (function(i){
    return function(){
      console.log(i)
    }
  })(i)
}

ele[0].onclick()

// 用块级作用域
var ele = [{},{},{}]
for(let i=0;i<3;i++){
  ele[i].onclick = function(){
    console.log(i)
  }
}

ele[0].onclick()

const 在 let 的基础上多了一个只读。不能改变内存地址,可以改变内存数据

解构

赋值默认值:

const {foo = ''} = obj; // 默认值
const {code:otherCode} = res; // 设置别名
[b,a] = [a,b] // 交替变量

const obj = {b:{foo:1}}

const {a:{foo} ={}/** 假设没有解构到 a,此时的foo、也是会错的 */} = obj;

console.log(foo) //  foo 1
// console.log(a) // a is not defined

模板字符串

const msg = `name ${1+2}`;

// 带标签的模板字符串  使用场景:实现模板引擎 
const name = 'tom'
const gender = false

function myTagFunc(strings,...args){
  // strings 获取到的除占位符以外的数组 [ 'hey,', ' is a ', '' ]
  // args 获取到的是占位符的数组
  console.log(strings,args)
}

const result = myTagFunc`hey,${name} is a ${gender}`

函数对模板字符串进行处理

function safe(strArr) {
  let res = '';
  console.log(arguments);
  for(var i=0, len = strArr.length; i < len; i++) {
    res += strArr[i].replace(//g, '>');
    if(i < arguments.length -1) {
      res += arguments[i + 1];
    }
  }
  return res;
}
let name = 'Joh';
var result = safe`

hello ${name}

`; console.log(result); // <p>hello Joh</p>

字符串查找

  • includes
  • endsWith
  • startsWith

参数默认值,严格等于undefined

function a(bar){
  var foo = bar || 0;  // 此时如果是 false或者0;就会赋值为0
}

function b(bar = 0){
  console.log(bar)
}

... 运算符

  • 剩余参数
  • 只能出现在形参的最后一位
  • 数组的形式接收实参列表

 

const arr = ['foo','bar','baz'];
console.log.appy(console,arr)
console.log(...arr)

 

箭头函数,没有自己的this

this : 箭头函数不会改变this的指向。箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this就继承了定义函数的对象。

const obj = {
  name:'tom',
  sayAsync:function(){
    setTimeout(()=>{
      console.log(this.name) // 继承了sayAsync
    })
  }
}

obj.sayAsync() //  tom


function newObj(){
  this.a = 2;
  return ()=>{ // 继承了newObj
    console.log(this.a)
  }
}

const b = newObj()
b() // 2
  • Object.assign // 一般这个方法我会用... 去代替
  • Object.is // Object.is(NaN,NaN) 一般不会用到这个方法
  • 非侵入式

Proxy

const person = {
  name:'xx',
  age:20
}

// 代理模式  TODO:代理模式在前端的应用,vue3的数据响应,替代vue2的defineProperty
const personProxy = new Proxy(person,{
  get(target,property){
    console.log(target,property)
    return 'sss'
  },
  set(target,property,value){
    target[property] = 200
  }
})


console.log(personProxy.name) //sss

personProxy.age = 2000
console.log(personProxy.age) //200

ECMAScript流水账_第1张图片

  • 相比defineProperty有更多的操作空间
  • 对数组进行操作,比如以前是修改原来原本的push方法
const list = [];

const listProxy = new Proxy(list,{
  set(target,property,value){
    console.log('set',property,value)
    target[property] = value;
    return 'greater'
  }
})

listProxy.push(1);

console.log(listProxy) // [1]

Reflect:(统一提供一套用于操作对象的方法)

Reflect 成员方法就是Proxy处理对象的默认实现

const person = {
  name:'xx',
  age:20
}

// 如果没有定义get,相当于默认为以下操作
const personProxy = new Proxy(person,{
  get(target,property){
    return Reflect.get(target,property)
  }
})
const obj = {
  name:'xx',
  age:20
}

// console.log('name' in obj)
// console.log(delete obj['age'] )
// console.log(Object.keys(obj))

console.log(Reflect.has(obj,'name'))
console.log(Reflect.deleteProperty(obj,'age'))
console.log(Reflect.ownKeys(obj))

Promise TODO

class 类 TODO 与 new Obj() 的区别

实例方法,静态方法

Set 数据结构:最常用来数组去重。。。。

const result = [...new Set([1,2,3,1,2])]

Map 数据结构

相对{}能够以对象作为Key.

和set一样有 foreach , for ... of 方法

Symbol

每次创建都是唯一值 Symbol

作为Key值独一无二,私有成员

const name = Symbol()
const person = {
 [name]:'xx',
 say(){
   console.log(this[name])
 }
}

// other.js
person.say()

通过for in 方法或者 Object.keys ,JSON.stringify()是拿不到这个属性名的
可以通过 Object.getOwnPropertySymbols(obj)拿到

 

Symbol.for('foo') = Symbol.for('foo') // todo 这样做为何不直接 'foo' === 'foo'

for ... of (iterable接口)

代替foreach 可终止循环

遍历Map

object 不可被迭代,使用for of 会报错,因为他没有实现iterable

const m = new Map();
m.set('foo','123')
m.set('bar','456')

for(const [key,value] of m){
  console.log(key,value)
}
const m = new Map();
m.set('foo','123')
m.set('bar','456')

const iterator = m[Symbol.iterator]()


console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
console.log(iterator.next())
// { value: [ 'foo', '123' ], done: false }
// { value: [ 'bar', '456' ], done: false }
// { value: undefined, done: true }
// { value: undefined, done: true }
// { value: undefined, done: true }

实现迭代器:

// 迭代器模式

const obj = {
  store:['foo','bar'],
  [Symbol.iterator]:function(){
    let index = 0;
    const self = this;

    return {
      next:function(){
        const result = {
          value:self.store[index],
          done:index >= self.store.length
        }
        index++
        return result
      }
    }
  }
}

for(const item of obj){
  console.log('循环体',item)
}

迭代器的意义:对外提供统一遍历接口

const todos = {
  life:['吃饭','睡觉','打豆豆'],
  learn:['语文','数学','英语'],
  work:['摸鱼'],
  each: function(callback){
    const all = [].concat(this.life,this.learn,this.work)
    for(const item of all){
      callback(item)
    }
  },

  [Symbol.iterator]: function(){
    const all = [...this.life,...this.learn,...this.work]
    let index = 0;
    return {
      next:function(){
        return {
          value:all[index],
          done: index++ >= all.length
        }
      }
    }
  }
}

for(const item of todos){
  console.log('循环体',item)
}

生成器 Generator

返回一个生成器对象

// 案例1: 发号器

function *createIdMaker(){
  let id = 1;
  while(true){ // 不需要担心死循环的问题
    yield id++
  }
}

const generator = createIdMaker()
console.log(generator.next())
console.log(generator.next())
console.log(generator.next())

// 改进 函数实现iterator方法
const todos = {
  life:['吃饭','睡觉','打豆豆'],
  learn:['语文','数学','英语'],
  work:['摸鱼'],
  each: function(callback){
    const all = [].concat(this.life,this.learn,this.work)
    for(const item of all){
      callback(item)
    }
  },

  [Symbol.iterator]: function *(){
    const all = [...this.life,...this.learn,...this.work]
    for(const item of all){
      yield item
    }
  }
}

for(const item of todos){
  console.log('循环体',item)
}

Esmodule TODO

ES2016

Array的includes

2**2 === Math.pow(2,2)

ES2017

Object.values(obj)

Obejct.entries(obj)

对象转Map

const obj = {a:1}
console.log(new Map(Object.entries(obj)))

String.prototype.padStart

String.prototype.padEnd

const books = {
  html:5,
  js:6,
  javascript:12
}

for (const [name,count] of Object.entries(books)) {
  console.log(`${name.padEnd(16,'-')}|${count.toString().padStart(3,'0')}}`)
}


html------------|005
js--------------|006
javascript------|012

async await TODO

 

你可能感兴趣的:(Javascript,基础)