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

时间:2018-09-12 10:13:06

标签: javascript oop

现在我有一个对象,例如这支笔。

该类的原型包含一系列功能和其他属性。

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');

有没有避免修改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;
}

3 个答案:

答案 0 :(得分:4)

您可以将笔包在Proxy中并定义适当的处理程序。

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');

答案 1 :(得分:2)

您可以用调用原始函数的包装程序替换函数,也可以执行其他操作。例如:

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然后调用原始函数的包装程序替换console.log上的所有功能(仅是其自身的功能,而不是其继承的功能)。

实时示例:

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');

您可以对其进行调整,以处理从原型继承的或仅从Pen.prototype继承的函数(目前Pen.prototype上没有任何东西),等等。

答案 2 :(得分:2)

您可以编写一个返回另一个函数的函数:

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
};