Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何修改对象中每个函数的行为?_Javascript_Oop - Fatal编程技术网

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

Javascript 如何修改对象中每个函数的行为?,javascript,oop,Javascript,Oop,现在我有一个物体,比如这支笔 该类的原型包含一系列函数和其他属性 var Pen=function(){ this.inkColor='red'; this.write=函数(文本){ 文件。书写(文本); } this.refill=函数(){ 控制台日志(“重新填充”); } this.getInkColor=函数(){ 返回此.inkColor; } }; var pen=新笔(); pen.write(pen.getInkColor()+':Hello')您可以使用调用原始函数并执行其

现在我有一个物体,比如这支笔

该类的原型包含一系列函数和其他属性

var Pen=function(){
this.inkColor='red';
this.write=函数(文本){
文件。书写(文本);
}
this.refill=函数(){
控制台日志(“重新填充”);
}
this.getInkColor=函数(){
返回此.inkColor;
}
};
var pen=新笔();

pen.write(pen.getInkColor()+':Hello')您可以使用调用原始函数并执行其他操作的包装器替换函数。例如:

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=函数(文本){
//使用console.log而不是document.write
console.log(文本);
}
this.refill=函数(){
控制台日志(“重新填充”);
}
this.getInkColor=函数(){
返回此.inkColor;
}
};
var pen=新笔();
Object.keys(笔).forEach(名称=>{
const originalFunction=笔[名称];
if(原始函数的类型==“函数”){
笔[名称]=函数(…参数){
console.log(名称,args);
返回originalFunction.apply(this,args);
};
}
});

pen.write(pen.getInkColor()+':Hello')您可以编写一个返回另一个函数的函数:

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

您可以将笔包装在一个容器中,并定义适当的处理程序

var Pen=function(){
this.inkColor='red';
this.write=函数(文本){
文件。书写(文本);
}
this.refill=函数(){
控制台日志(“重新填充”);
}
this.getInkColor=函数(){
返回此.inkColor;
}
};
变量处理程序={
get:函数(目标、名称){
在target?函数(…args){console.log('Hello World')中返回名称;返回目标[name](args)}:未定义;
}
};
var pen=新笔();
var p=新代理(笔、处理程序);

p、 写(p.getInkColor()+':Hello')
FWIW,
Pen
没有原型。构造函数将实例方法分配给普通对象。是的,它分配了,它只有一个空的。啊,我的错误。即使这样,有没有重构这个对象的方法呢?问题是,我不能更改Pen类(如果它是一个类)内部的现有代码。我不知道里面到底有多少函数,所以我必须迭代它们。@t.J.Crowder你完全正确-我会编辑答案。这里有些东西混在一起了。浩武使用@bnord的解决方案。在这种情况下,代理是绝对合理的。这有点像我尝试的第一件事,但不知怎的,我最终陷入了一个无休止的循环。。。因为我没有使用apply函数。@HaoWu-:-)可能是您使用了
return pen[name](…)
,它再次调用包装器,而不是调用原始函数。上述方法之所以有效,是因为它调用的是原始的,而不是包装器。这在正常情况下效果很好,但不幸的是,我也无法更改对象实例化部分。因为这个对象中有很多是在其他地方实例化的,所以如果笔是一个原型,我必须动态修改它的实际代码。