javascript - Intercept calls to constructor - Stack Overflow

I am having a bit of trouble intercepting constructor calls to a library (so I can replay them later) w

I am having a bit of trouble intercepting constructor calls to a library (so I can replay them later) while still maintaining the prototype chain. More concretely, I am working with a library (ThreeJS, but could be any library), and some code that uses this library. What I want to do is write a piece of code that modifies the library objects, so I can run a block of code every time a constructor is called.

Example: when a new scene is created, I want to print "new Scene created" to the console.

var scene = new THREE.Scene();

When the constructor takes arguments, I also want to log these arguments.

I am having a bit of trouble intercepting constructor calls to a library (so I can replay them later) while still maintaining the prototype chain. More concretely, I am working with a library (ThreeJS, but could be any library), and some code that uses this library. What I want to do is write a piece of code that modifies the library objects, so I can run a block of code every time a constructor is called.

Example: when a new scene is created, I want to print "new Scene created" to the console.

var scene = new THREE.Scene();

When the constructor takes arguments, I also want to log these arguments.

Share Improve this question edited Apr 8, 2015 at 15:39 Mathias Bak asked Apr 8, 2015 at 15:34 Mathias BakMathias Bak 5,1556 gold badges33 silver badges42 bronze badges 2
  • 1 Might be missing the point, but if you are the one calling new ... could you not just log the information yourself? – Joey Ciechanowicz Commented Apr 8, 2015 at 15:36
  • My goal is to edit neither the library code or the code calling new, but only a third file that intercepts the constructor calls. – Mathias Bak Commented Apr 8, 2015 at 15:38
Add a ment  | 

4 Answers 4

Reset to default 6

I'm not sure about this, but... you could try something like...

// Backup the original constructor somewhere
THREE._Scene = THREE.Scene;

// Override with your own, then call the original
THREE.Scene = function() {
  // Do whatever you want to do here..
  THREE._Scene.apply(this, arguments);
}

// Extend the original class
THREE.Scene.prototype = Object.create(THREE._Scene.prototype);

Using proxy:

THREE.Scene = new Proxy(THREE.Scene, {
    construct(target, args) {
        console.log(`creating a ${target.name} with ${args}`);
        return new target(...args);
    }
});

Starting from @bvaughn code, this worked for me:

THREE._Scene = THREE.Scene;

THREE.Scene = function() {
  const Scene = Function.prototype.bind.apply(THREE._Scene, arguments);
  const scene = new Scene()
  console.log("Intercepted scene:", scene)
  return scene;
}

THREE.Scene.prototype = Object.create(THREE._Scene.prototype);

// Test
const scene = new THREE.Scene()
// Prints "Intercepted scene:", ....

The "Using proxy" answer by Yoz is correct for modern times (thanks!), however it doesn't quite work for a class implementation since you can't redefine the class's name as a variable.

Here's my example using a class. Here this is used to implement a typical "singleton" pattern (where only one instance of a class should ever exist).

It's in TypeScript, but just remove the type annotations and it will work in JS.

// Only one instance can exist per application so the actual implementation class
// is hidden behind a Proxy (below). Thus we implement the singleton pattern.
class MySingletonImpl {
    constructor() { /* ... */ }
}

var instance: MySingletonImpl | null = null;

// Proxy the implementation's constructor to ensure only one instance ever exists.
export const MySingleton = new Proxy(MySingletonImpl, {
    construct(target, args) {
        if (!instance)
            instance = new target(...args);
        return instance;
    }
});

VSCode, at least, is smart enough to see the proxy and still provides full hinting/checking support for the members of the actual implementation class. Don't know about other editors though.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744769652a4592681.html

相关推荐

  • javascript - Intercept calls to constructor - Stack Overflow

    I am having a bit of trouble intercepting constructor calls to a library (so I can replay them later) w

    6小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信