向所有函数添加一行代码

IT技术 javascript class coffeescript
2021-03-17 10:16:46

所以我在 JS 中工作了很多,我在事件方面做了很多工作(尽量保持module化)。当前我Event.fire('eventName')在每个函数结束时调用我正在寻找一种方法让我的对象/类中的任何函数在Event.fire([function name])所有函数的末尾自动调用

例子:

function MyClass(){
   this.on('someFunc', this.funcTwo);
   this.someFunc();
}
MyClass.prototype.on = function( event ){
   // the event stuff //
}
MyClass.prototype.someFunc = function(){
   console.log('someFunc');
}
MyClass.prototype.funcTwo = function(){
   console.log('funcTwo');
}
3个回答

你可以尝试这样的事情,动态修改你的函数:

var obj = MyClass.prototype;
for (var prop in obj)
    if (typeof obj[prop] == "function") // maybe also prop != "on" and similar
        (function(name, old) {
            obj[prop] = function() {
                var res = old.apply(this, arguments);
                Event.fire(name);
                return res;
            };
        })(prop, obj[prop]);
不。您必须在将方法分配给原型对象后,为每个类(将其包装在一个函数中)显式执行此操作。顺便说一句,如果您使用继承,您也可以添加一个hasOwnProperty检查。
2021-04-21 10:16:46
最终使用此选项,创建了一个包含代码的 github 存储库,任何人都希望这样做:github.com/qrpike/JS-Eventted-Extender
2021-04-22 10:16:46
现在试试这个,效果很好。有没有办法把它作为超类,而我的其他类继承它?所以我不必为我所有的类/对象都这样做?谢谢!
2021-04-25 10:16:46

您可以创建一个函数来构建始终具有该功能的函数:

var eventFunctionFactory = function(fn, e) {
  if (typeof fn != 'function' || typeof e != 'function') {
    throw new TypeError('Invalid function!');
  }

  return function(/* arguments */) {
    // Convert arguments to array
    var args = Array.prototype.slice.call(arguments);

    // Fire event
    Event.fire(e);

    // Call the function with the applied arguments
    // Return its result
    return fn.apply(fn, args);
  };
};

var myClass = function() {
  this.someFunction = eventFunctionFactory(
                        // Function
                        function(a, b) {
                          return a + b;
                        },

                        // Event
                        function() {
                          console.log('someFunction fired!');
                        }
                      );
};

var myObj = new myClass();

// Outputs:
// someFunction fired!
// 3
console.log(myObj.someFunction(1, 2));
我的答案与@Bergi 的答案基本相同;但是他会自动转换您的功能,而对于我的功能,您可以明确地执行此操作。
2021-04-22 10:16:46
仅当您需要它作为数组时 - 但也apply需要纯Arguments对象。
2021-04-24 10:16:46
公平点 :)slice对于没有数组泛型的旧浏览器,不需要参数吗?
2021-05-05 10:16:46
然而,你不需要slicearguments,该事件应触发的功能和OP的Event.fire似乎是一个字符串,而不是一个函数参数。
2021-05-17 10:16:46

最简单的方法是拥有一个代理类。假设您的常规类是 A 类,代理类是 B 类。 B 类在内部有一个 A 类实例。类 B 也有每个 A 类函数的存根,该函数将其内部类称为实例。然后,您可以通过简单地将代码添加到关联的存根(在对类 A 的函数调用之前或之后)添加您想要的任何代码到原始类。

为了能够使用增强的类,您需要做的就是修改应用程序的其余部分以实例化类 B 而不是类 A。这种方法的优点是您的原始类保持不变。

@QuintonPike:它看起来有点像我的解决方案,只是您写入新类的原型而不是覆盖所有内容。
2021-04-28 10:16:46