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); //橙 红