简体   繁体   English

如何修改对象中每个函数的行为?

[英]How can I modify the behavior of every function in an object?

Right now I have an object, such as this Pen. 现在我有一个对象,比如这支笔。

The prototype of the class contains a series of functions and other properties. 该类的原型包含一系列函数和其他属性。

 var Pen = function(){ this.inkColor = 'red'; this.write = function(text){ document.write(text); } this.refill = function(){ console.log('refilling'); } this.getInkColor = function(){ return this.inkColor; } }; var pen = new Pen(); pen.write(pen.getInkColor() + ': Hello'); 

Is there away to avoid modifying the Pen class, but change the behavior of every function it has, such as print a log before the actual function call? 有没有避免修改Pen类,但改变它所具有的每个函数的行为,例如在实际函数调用之前打印日志?

this.write = function(text){
   // do something first
   document.write(text);
}

this.refill = function(){
   // do something first
   console.log('refilling');
}

this.getInkColor = function(){
   // do something first
   return this.inkColor;
}

You can wrap your pen in a Proxy and define an appropriate handler. 您可以将笔包裹在代理中并定义适当的处理程序。

 var Pen = function(){ this.inkColor = 'red'; this.write = function(text){ document.write(text); } this.refill = function(){ console.log('refilling'); } this.getInkColor = function(){ return this.inkColor; } }; var handler = { get: function(target, name) { return name in target ? function (...args) {console.log('Hello World'); return target[name](args)} : undefined; } }; var pen = new Pen(); var p = new Proxy(pen, handler); p.write(p.getInkColor() + ': Hello'); 

You can replace the functions with wrappers that call the original and also do something else. 您可以使用调用原始函数的包装器替换函数,也可以执行其他操作。 For instance: 例如:

Object.keys(pen).forEach(name => {
    const originalFunction = pen[name];
    if (typeof originalFunction === "function") {
        pen[name] = function(...args) {
            console.log(name, args);
            return originalFunction.apply(this, args);
        };
    }
});

That replaces all functions on pen (only its own, not ones it inherits) with wrappers that first do a console.log then call the original. 它取代了pen上的所有函数(只有它自己的,而不是它继承的函数)和首先执行console.log然后调用原始函数的包装器。

Live Example: 实例:

 var Pen = function(){ this.inkColor = 'red'; this.write = function(text){ // used console.log instead of document.write console.log(text); } this.refill = function(){ console.log('refilling'); } this.getInkColor = function(){ return this.inkColor; } }; var pen = new Pen(); Object.keys(pen).forEach(name => { const originalFunction = pen[name]; if (typeof originalFunction === "function") { pen[name] = function(...args) { console.log(name, args); return originalFunction.apply(this, args); }; } }); pen.write(pen.getInkColor() + ': Hello'); 

You can tweak that to handle functions inherited from the prototype, or inherited only from Pen.prototype (you don't have anything on Pen.prototype at present), etc. 你可以调整它来处理从原型继承的函数,或者只从Pen.prototype继承(你目前在Pen.prototype上没有任何东西),等等。

You could write a function that returns another function: 你可以编写一个返回另一个函数的函数:

function doSomethingFirst(somethingToDoFirstFn, thingToDoAfterFn) {
  return function() {
    somethingToDoFirstFn.apply(null, arguments);
    thingToDoAfterFn.apply(null, arguments);
  }
} 

var Pen = function(){
   // code

   this.refill = doSomethingFirst(function(){
      console.log('somethingFirst');
   }, function() {
      console.log('refilling');
   })   

   // code
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM