【问题标题】:Javascript. Hooking into new MyClass()Javascript。挂钩 new MyClass()
【发布时间】:2022-01-07 22:55:55
【问题描述】:

我想在 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.

我知道我可以创建自己的方法 function Create() { new F().init() }

但我想知道是否有办法挂钩 new 函数调用?

我希望你明白我的意思。

【问题讨论】:

  • 应该准确提醒什么,按什么顺序?
  • 没有顺序,只是第二个@OrangeDog 的答案就是我要找的那个。

标签: javascript


【解决方案1】:

new 不是函数调用,F() 是。您可以这样做,将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();

如果你想要一个实用函数来做这种事情:

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

或使用提供这些东西的许多框架/库(ExtJS、jQuery、Prototype)之一。

以下讨论

这可以让您开始尝试做的事情,但我不保证它适用于所有情况或实现(仅在 V8 上测试)。您可以将 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); }});

【讨论】:

  • 谢谢,这正是我的意图!但是:( ...有没有办法做到这一点,而不是直接访问F类,而是一个参数(传递它)...函数(clazz){clazz = function(){clazz.apply (this, arguments); this.init(); } ... javascript 中有没有办法设置引用而不是参数?:S
  • 不确定你在问什么。如果你打电话给new F(),你怎么可能无法访问F
  • 我的意思是,我不能直接访问 F。我有一个方法需要 F、G、H 等等,我想对它们中的每一个都做同样的事情.这就是为什么我要声明一个方法,该方法接受一个类(或您所称的构造函数)并重写该类。基本上是 rebind(clazz) { // 在这个方法中做所有的魔法)...所以我可以通过引用访问 F = clazz.我宁愿不必返回任何东西,而是在方法中设置 clazz。我知道这在 OO 语言中很困难。我希望所有对象都有一个方法调用,obj.replaceMe(...) 什么的
  • 我称它为构造函数,因为它就是这样; JavaScript 中没有类、方法或引用之类的东西。 JavaScript 中没有与 C++ 指针或引用等价的东西,所以你问的是不可能的(也是不必要的)。尝试阅读 JavaScript 中的作用域和继承。
  • 是的,是的。通常对于像你这样的人来说,会陷入非常烦人的语义(不仅仅是你自己)。来自 crockford 本人:crockford.com/javascript/inheritance.html “首先,我们将创建一个 Parenizor 类,该类将为其值设置和获取方法,以及将值包装在括号中的 toString 方法。”我想说的是,各种语言中各种事物的词混合使用,但你应该专注于我写作的意图,而不是被这样的东西挂断。 Java 中也不存在引用
【解决方案2】:

javascript 中的构造函数与任何其他方法一样,您真正要查找的是 javascript 中的AOP

请参阅this SO question 了解一些优秀的 JavaScript AOP 库。

【讨论】:

    【解决方案3】:

    您可以使用handler.construct() of Proxy 来挂钩新的操作员。在这里,我更改了传递给 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'
    });
    

    【讨论】:

      猜你喜欢
      • 2017-03-09
      • 2010-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      相关资源
      最近更新 更多