admin管理员组文章数量:1391775
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
4 Answers
Reset to default 6I'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.
本文标签: javascriptIntercept calls to constructorStack Overflow
版权声明:本文标题:javascript - Intercept calls to constructor - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744769651a2624261.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论