如何猴子修补对象的构造函数?

发布于 2024-12-21 15:24:57 字数 501 浏览 3 评论 0原文

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

// 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...

I'd like to monkey patch the constructor for this 'Controller' object. But how do I monkey patch the constructor function so I can still call the original? This is what I've tried.

// 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...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

再见回来 2024-12-28 15:24:57

您似乎想做类似的事情:

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;

现在您有了一个包含所有旧方法的新构造函数。或者执行上述两项操作。只需用简单的英语说出您想做的事情即可。

You seem to want to do something like:

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

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

Now all instances get the new tag method and you can still call oldTag if you want (or put it back).

Or perhaps you want to do something like:

var oldConstructor = Constructor;

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

So now you have a new constructor with all the old methods. Or do both the above. Just use plain English to say what you want to do.

可可 2024-12-28 15:24:57

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

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

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

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

The cleaner way is not monkey patching the constructor: put the constructor logic in a separate init method and monkey patch / inherit that instead.

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

You can also consider building objects with a builder function

function make_fancy_obj(){
    var obj = new Constructor();
    obj.foo = 'bar';
    return obj;
}
妥活 2024-12-28 15:24:57

构造函数可以选择返回不同的 this,它将覆盖 new 语句本身生成的任何内容 - 这是您的示例更正和注释:

// 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() {
const instance = new original(...arguments); //

Constructor functions may optionally return a different this, which will override whatever is generated by the new statement itself - here's your example corrected and annotated:

// 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() {
    const instance = new original(...arguments); // ???? call the original constructor
    instance._tag = 'patched'; // patch
    return instance; // ???? return your replacement instance
}

var c = new Controller();
c.tag(); // ???? works

You can try it here:

https://jsfiddle.net/mindplay/qc8Lf7ae/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文