简体   繁体   English

Javascript。 挂钩 new MyClass()

[英]Javascript. Hooking into new MyClass()

I would like to do some stuff after before or after new has run.我想在 new 运行之前或之后做一些事情。

function F() {

    this.init = function  () { alert(0) }

}

F.prototype.init = function () { alert(1) }

new F().init(); // Will not run mine, because on new F(), init is reassigned within the class.

I understand I can create my own method function Create() { new F().init() }我知道我可以创建自己的方法 function Create() { new F().init() }

But I was wondering if there is a way to hook into the new Function call ?但我想知道是否有办法挂钩新的函数调用?

I hope you understand what I mean.我希望你明白我的意思。

new is not a function call, F() is. new不是函数调用, F()是。 You could do something like this, replacing F with your own delegate. 您可以执行以下操作,将F替换为您自己的委托。

function F() {
    this.init = function  () { alert(0) }
}

var oldF = F;
F = function() {
    oldF.apply(this, arguments);
    this.init = function() { alert(1); };
};

new F().init();

If you want a utility function to do this kind of thing: 如果您希望实用程序函数执行此类操作:

function wrap(constructor, config) {
    return function() {
        constructor.apply(this, arguments);
        for (var key in config) {
            this[key] = config[key];
        }
    }
}

F = wrap(F, {init: function() { alert(1); }});

or use one of many frameworks/libraries (ExtJS, jQuery, Prototype) that provides this stuff. 或使用提供此功能的许多框架/库(ExtJS,jQuery,Prototype)之一。

Following discussion 以下讨论

This can start you off on what you're trying to do, but I don't guarantee it works in all situations or implementations (only tested on V8). 这可以让您开始尝试做的事情,但是我不能保证它在所有情况或实现下都有效(仅在V8上进行了测试)。 You could pass the context in which F exists as an additional parameter, or make sure you apply/bind/call extend with it. 您可以将F存在的上下文作为附加参数传递,或确保对其进行应用/绑定/调用extend

function extend(constructor, config) {
    this[constructor.name] = function() {
        constructor.apply(this, arguments);
        for (var key in config) {
            this[key] = config[key];
        }
    }
}

extend(F, {init: function() { alert(1); }});

You can use handler.construct() of Proxy to hook the new Operator.您可以使用Proxy 的 handler.construct()来挂钩新的 Operator。 Here I alter the arguments passed to the new WebSocket() call:在这里,我更改了传递给 new WebSocket() 调用的参数:

let WebSocket = require('ws');
// let's hook the new WebSocket(...)
WebSocket = new Proxy(WebSocket, {
  construct: function(target, args, newTarget) {
    // https://github.com/websockets/ws/blob/8.4.0/lib/websocket.js#L51
    let [address, options] = args;  // the original constroctor actually has tree arguments, here we only use 2, to keep it simple

    const extraOptions = createWsOptions(address);

    options = {
      ...options,
      ...extraOptions
    };
    console.log(`options of new Websocket(): ${JSON.stringify(options, null, 2)}`);

    return new target(...[address, options]);
  }
});
ws = new WebSocket(aServer, {
  protocol: 'binary'
});

Constructors in javascript are just like any other methods, what you're really looking for is AOP in javascript. javascript中的构造方法与其他方法一样,您真正要寻找的是javascript中的AOP

See this SO question for some good AOP libraries for javascript. 有关适用于JavaScript的一些好的AOP库,请参见此问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM