ES6:按名称调用实例函数

时间:2017-07-28 10:37:42

标签: javascript jquery ecmascript-6

我的下一课有很多功能:

class EventUtils {

    constructor(pid) {}
bindEvent1{}
bindEvent2()
...
}

我必须运行这些功能。在ES5之前,我使用了something like thisthis方法

然而,在重写为ES6类之后,这些示例不再起作用了。 我曾尝试过下一个代码:

let eventUtils = new EventsUtils();

  Object.getOwnPropertyNames(eventUtils.__proto__).forEach((name) => {

     if (name.indexOf('bind') > -1) {                                        
        let fn = eventUtils[name];
        if (typeof fn === "function") fn.apply(null);
         }
   });

但是这样我在应用函数中没有定义this的范围。 这种编码的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

参考 proto 是你可以做的最糟糕的事情之一(它要么不起作用,要么它会杀死任何优化),也许一个简单的for循环可以帮助:

for(let key of Object.getOwnPropertyNames(Object.getPrototypeOf(eventUtils))){
 if(key.includes("Event") && typeof eventUtils[key] === "function"){
   eventUtils[key]();
 }
}

但是,动态变量名称总是一个坏主意......

答案 1 :(得分:2)

假设您要调用的所有函数都是在原型中定义的,您可以将自定义bindAll方法添加到原型中。然后只需在实例eventUtils.bindAll()

上调用它

但是在原型中拥有数十甚至数百个功能的想法似乎很奇怪。你最好只使用一组函数来调用。所以你可以轻松添加,删除它们等等。



class EventUtils {
    constructor(pid) {
      this.pid = pid
    }
    
    bindEvent1() {
      console.log(`event 1 for ${this.pid}`)
    }

    bindEvent2() {
      console.log(`event 2 for ${this.pid}`)
    }
    
    bindEvent3() {
      console.log(`event 3 for ${this.pid}`)
    }
}

const addBindAll = ({prototype}) => {
 const fns = Reflect.ownKeys(prototype)
     .filter(key => key.startsWith('bind') && typeof prototype[key] === 'function' )
 
 Reflect.defineProperty(prototype, 'bindAll', {
  value: function() {
    fns.forEach(fn => this[fn]())
  },
  enumerable: false
 })
}

addBindAll(EventUtils)

let utils = new EventUtils(666)

utils.bindAll()