ES6语法

作者: lmmy123 | 来源:发表于2019-02-12 14:44 被阅读7次

    ES6 Module

    在 ES6 Module出现之前,有3种模块化方案
    • AMD 浏览器端
    • CMD 服务器端
    • CommonJs 服务器端
    ES6 Module export
    • export {<变量>} 导出的是一个变量的引用,当变量改变时,import 导入的变量也会改变
    • export default 导出的是一个值的拷贝,当变量改变是, import导入的变量不会改变
    ES6 Module vs CommonJs 区别
    • CommonJs 输出的是一个值的拷贝,ES6 Module种export {<变量>}输出的是一个变量的引用,export deafult 输出的是一个值的拷贝
    • CommonJs运行在服务器上,运行时加载,ES6 Module时静态的输出一个接口,发生在编译的阶段
    • CommonJs 在第一次加载的时候运行一次, 之后加载返回的都是第一次的结果,具有缓存的效果, ES6 Module 则没有
    ES6 Module import

    ES6 Module静态编译的特点,导致了无法动态加载,但是总是会有一些需要动态加载模块的需求,所以现在有一个提案,使用把import作为一个函数可以实现动态加载模块,它返回一个Promise,Promise被resolve时的值为输出的模块

    import('./module.js').then(res=>{
      ...
    })
    

    Vue中路由的懒加载的ES6写法就是使用了这个技术

    Proxy

    Object.defineProperty的增强版

    let obj = {}
    obj = new Proxy(obj, {
      set(target, key, val) {
        console.log('oops')
        return  Reflect.set(target, key, val)
      }
    })
    obj.foo = 'bar'
    
    • handler.apply
      apply 可以让我们拦截一个函数的执行,我们可以把它用在函数节流中
    const proxy = (func, time) => {
      let previous = new Date(0).getTime()
      let handler = {
        apply(target, context, args) {
          let now = new Date().getTime()
          if(now - previous > time) {
            previous = now
            Reflect.apply(func, context, args)
          }
        }
      }
      return new Proxy(func, handler)
    }
    
    DOM.addEventListener('mousemove', proxy(handler, TIME))
    
    • handler.contruct
      contruct 可以拦截通过new关键词调用这个函数的操作, 我们可以用在单例模式中
    function proxy(func) {
      let instance
      let handler = {
        construct(target, args) {
          if(!instance) {
            instance = Reflect.construct(func, args)
          }
          return instance
        }
      }
      return new Proxy(func, handler)
    }
    function Person(name, age) {
      this.name = name
      this.age = age
    }
    const SingletonPerson = proxy(Person)
    let person1 = new SingletonPerson('zhl', 22)
    let person2 = new SingletonPerson('syw', 22) //这个实例不会生成
    console.loa(person1 ===  person2) //true
    
    • handler.defineProperty
      defineProperty可以拦截对这个对象的Obeject.defineProperty操作
      注意对象内部的默认的[[SET]]函数(即对这个对象的属性赋值)会间接触发defineProperty和getOwnPropertyDescriptor这2个拦截方法
    function onChange(obj, callback) {
      const handler = {
        get(target, key) {
          try{
              return new Proxy(target[key], handler)
          }catch(e) {
             Reflect.get(target, key)
          }
        },
        defineProperty(target, key, descriptor) {
          callback()
          return Reflect.defineProperty(target, key, descriptor)
        }
      }
      return new Proxy(obj, handler)
    }
    let obj = onChange({}, () => {
      console.log('oops')
    })
    obj.a = {} //'oops'
    obj.a.b = 1 /'oops'
    

    相关文章

      网友评论

          本文标题:ES6语法

          本文链接:https://www.haomeiwen.com/subject/dlckeqtx.html