Как я могу изменить поведение каждой функции в объекте? - PullRequest
0 голосов
/ 12 сентября 2018

Прямо сейчас у меня есть объект, такой как этот Pen.

Прототип класса содержит ряд функций и других свойств.

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 голосов
/ 12 сентября 2018

Вы можете написать функцию, которая возвращает другую функцию:

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
};
0 голосов
/ 12 сентября 2018

Вы можете обернуть ручку в 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');
0 голосов
/ 12 сентября 2018

Вы можете заменить функции оболочками, которые вызывают оригинал, а также делают что-то еще.Например:

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) и т. Д..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...