关于javascript:Js高级API

46次阅读

共计 3966 个字符,预计需要花费 10 分钟才能阅读完成。

Decorator 装璜器

针对属性 / 办法的装璜器

// decorator 内部能够包装一个函数,函数能够带参数

    function Decorator (type) {
      /**
       * 这里是真正的 decorator
       * @description: 装璜的对象的形容对象
       * @target: 装璜的属性所述类的原型,不是实例后的类。如果装璜的是 Animal 的某个属性, 这个 target 就是 Animal.prototype
       * @name 装璜的属性的 key
       */

      return function (target, name, desciptor) {
        // 因为 babel 的缘故 通过 value 并不能获取值,以此能够获取实例化的时候此属性的默认值
        let v = desciptor.initializer && desciptor.initializer.call(this)
        // 返回一个新的形容对象,或者间接批改 desciptor 也能够
        return {
          enumerable: true, // 能够遍历
          configurable: true, // 能够删除
          get: function () {return v},
          set: function (c) {v = c}
        }
      }
    }
    
    
    
    
    // 下面的不能和业界商用的 Decorator 混用

    function Check (type) {return function (target, name, desciptor) {let v = desciptor.initializer && desciptor.initializer.call(this)
        // 将属性名字以及须要的类型的对应关系记录到类的原型上
        if (!target.constructor._checkers_) {
          // 将这个暗藏属性定义成 no enumerable, 遍历的时候是取不到的
          Object.defineProperty(target.constructor, '_checkers_', {value: {},
            enumerable: false,
            writable: true,
            configurable: true
          })
        }
        target.constructor._checkers_[name] = {type: type}
        return desciptor
      }
    }
    // 装璜函数的第一个参数 target 是包装属性所属的类的原型(prototype)// 也就是把对应关系挂载到了开发定义的子类上。

vue 中应用 Decorator

  • ts 开发肯定对 vue-property-decorator 不会感到生疏,这个插件提供了许多装璜器
  • 在 methods 外面的办法下面应用装璜器,这时候装璜器的 target 对应的是 methods。
  • 能够在生命周期钩子函数下面应用装璜器,这时候 target 对应的是整个组件对象。
  import {log,confirmation} from "./test"
  
  methods: {@log()
    name() {console.log("获取数据");
    },
    @confirmation('此操作将永恒删除文件, 是否持续?')
    deleteFile(data){// 删除文件操作}
  },
  mounted () {this.name()
  }

test.js

 import {MessageBox}from "element-ui"
export function confirmation(message){return function(target,name,descriptor){
        let oldValue = descriptor.value
        descriptor.value = function(...args){MessageBox.confirm(message,'提醒').then(oldValue.bind(this,...args)).catch(()=>{})
        }
        return descriptor
    }
}
export function log(){
    /**
     * @description: 
     * @param {*} target  对应 methods
     * @param {*} name 对应属性办法的名称
     * @param {*} descriptor 对应属性办法的修饰符
     * @return {*}
     */      
    return function(target,name,descriptor){console.log(target,name,descriptor);
      // 获取实例化的时候此属性的默认值
      const fn = descriptor.value
      /* 重写 */
      descriptor.value = function(...rest){console.log(` 调用 ${name} 办法打印的 `);
        fn.call(this,...rest)
      }
    }
  }

Iterator 迭代器

  • 目标是为不同的数据结构提供对立的数据拜访机制 次要为 for of 服务的( 当 for of 执行的时候,循环过程中会主动调用这个对象上的迭代器办法, 顺次执行迭代器对象的 next 办法,并把 next 返回后果赋值给 for of 的变量,从而失去具体的值
  • 迭代器对象,返回此对象的办法叫做迭代器办法 此对象有一个 next 办法 每次调用 next 办法都会返回一个后果值
  • 这个后果值是一个 object 蕴含两个属性 value 和 done
  • value 示意具体的返回值 done 是布尔类型的,示意汇合是否遍历实现或者后续还有可用数据,没有可用返回 true, 否则返回 false
  • 外部会保护一个指针 用来指向以后汇合的地位 每调用一次 next 办法 指针都会向后挪动一个地位(能够设想成数组的索引)

    代码实现

  getInterator(list){
    var i = 0;
    return {next:function(){var done = (i>=list.length);
        var value = !done ? list[i++]:undefined
        return {
          done:done,
          value:value
        }
      }
    }
  }
  
  
  var it = this.getInterator(['a','b','c'])
    console.log(it.next());// {done: false, value: 'a'}
    console.log(it.next());//{done: false, value: 'b'}
    console.log(it.next());//{done: false, value: 'c'}
    console.log(it.next());//{done: true, value: undefined}
可迭代对象
  • Symbol.Iterator 是一个表达式 返回 Symbol 的 Iterator 属性,这是一个预约好的类型为 Symbol 的非凡值
  • ES6 规定,只有在对象上部署了 Iterator 接口,具体实现为给对象增加 Symbol.Iterator 属性,此属性指向一个迭代器办法,这个迭代器会返回一个迭代器对象。
  • 而部署了这个属性,并且实现迭代器办法 返回的对象就是迭代器对象,此时这个对象就是可迭代的 能够被 for for 遍历

    实现一个可迭代对象

     getIterator(){
        let iteratorObj = {items:[100,200,300],
          [Symbol.iterator]: function(){
            var self = this
            var i =0
            return {next:function(){var done = (i>=self.items.length)
                var value = !done?self.items[i++]:undefined
                return {
                  done:done,
                  value:value
                }
              }
            }
          }
        }
        for(var item of iteratorObj){console.log(item); //100 200 300
        }
      }
      
      // 下面的对象就是可迭代对象,能够被 for of 遍历
      
      this.getIterator()
    for of 中断

    如果 for of 循环提前退出,则会主动调用 return 办法, 须要留神的是 return 办法必须有返回值,且返回值必须是一个 object

     var arr = [100, 200, 300]
        arr[Symbol.iterator] = function () {
          var self = this
          var i = 0
          return {next: function () {
              var done = i >= self.length
              var value = !done ? self[i++] : undefined
              return {
                done: done,
                value: value
              }
            },
            return (){console.log('提前退出');
              return { // 必须返回一个对象
                done:true
              }
            }
          }
        }
    
        for (var o of arr) {if(o == 200){break;}
          console.log(o) // 100   提前退出
        }

    除了 for of 会调用对象的 Iterator, 构造赋值也会

        var str = '123'
        let [a,b]=str
        console.log(a,b); // 1 2
    
        let map = new Map()
          map.set('q','1')
          map.set('a','2')
          map.set('b','3')
        let [c,d] = map
        console.log(c,d); //['q', '1'] ['a', '2']

    因为一般对象不是可迭代对象。

    自定义的可迭代对象进行解构赋值

     var interatorObj = {items: ['橙', '红', '白'],
          [Symbol.iterator]: function () {
            let i = 0
            let self = this
            return {next: function () {
                let done = i >= self.items.length
                let value = !done ? self.items[i++] : undefined
                return {
                  done: done,
                  value: value
                }
              }
            }
          }
        }
       let [a,b] = interatorObj
       console.log(a,b); // 橙 红 

正文完
 0