【问题标题】:How do I monkey patch an object's constructor function?如何猴子修补对象的构造函数?
【发布时间】:2012-01-21 18:16:24
【问题描述】:

我想为这个“控制器”对象修改构造函数。但是我如何修改构造函数以便我仍然可以调用原始函数?这是我尝试过的。

// original
function Controller() {
    this._tag = 'div';
}
Controller.prototype.tag = function() {
    console.log(this._tag);
}

var c = new Controller(); 
c.tag(); // -> 'div', as expected


// patch attempt
var original = Controller;
Controller = function() {
    original.apply(this);
    this._tag = 'patched'; // patch
}

var c = new Controller();
c.tag(); // no method tag, prototype appears wiped...

【问题讨论】:

  • RHS 函数表达式周围的分组运算符是多余的。 “构造函数”是在另一个函数内部声明的,因此您无法从外部访问它(除非缺少代码使其成为外部匿名函数或其他对象的属性)。因此,如果您想“猴子补丁”构造函数(无论这意味着什么),在您有注释的地方插入代码是唯一的方法。
  • @RobG 如果好奇:en.wikipedia.org/wiki/Monkey_patch 猴子修补属性或方法非常简单,但由于构造函数的特殊状态,我不知所措。您可能是正确的,这是不可能的,但我不确定您所说的原因。我将更新代码示例以反映。
  • 告诉我们如何用普通方法猴子路径并不是一个更好的代码示例。这只会让你更难看出你真正的问题是什么。
  • 你不能包装构造函数并在创建对象后修改它吗?即定义一个调用保存的旧构造函数的函数,然后对其进行修改并返回新对象。这通常在 python 中使用工厂模式完成。
  • @missingno 真相。再次编辑。

标签: javascript monkeypatching


【解决方案1】:

更简洁的方法不是猴子修补构造函数:将构造函数逻辑放在单独的 init 方法中,然后猴子修补/继承它。

function Constructor(){
    this.init();
}
Constructor.prototype.init = function(){ /*...*/ };

您也可以考虑使用构建器函数构建对象

function make_fancy_obj(){
    var obj = new Constructor();
    obj.foo = 'bar';
    return obj;
}

【讨论】:

  • 很遗憾,我无法访问原始构造函数。这就是为什么我要走这条路。您可以在不修改我示例中的原始内容的情况下执行此操作吗?
【解决方案2】:

你似乎想做这样的事情:

Constructor.prototype.oldTag = Constructor.prototype.tag;

Constructor.prototype.tag = function() {/* whatever */};

现在所有实例都获得了新的 tag 方法,您仍然可以根据需要调用 oldTag(或将其放回去)。

或者也许你想做一些类似的事情:

var oldConstructor = Constructor;

 var Constructor = function () { /* new constructor */ };
 Constructor.prototype = oldConstructor.prototype;

所以现在你有了一个包含所有旧方法的新构造函数。或者以上都做。用简单的英语说你想做的事。

【讨论】:

  • 谢谢。到目前为止,我想做的似乎是不可能的。
猜你喜欢
  • 2014-04-19
  • 1970-01-01
  • 2017-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-27
  • 2012-03-13
  • 2013-12-26
相关资源
最近更新 更多