最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How can I cleanly monkey patch a function in Javascript? - Stack Overflow

programmeradmin5浏览0评论

Having a low level C/assembly programming background, one thing I was wondering is whether it is possible in Javascript to detour a function, meaning, replacing it with a function that I defined and then call the original one, to add additional code or hook that function.
I already found examples, but all of them are not what I would qualify clean, involve creating additional variables, etc

Having a low level C/assembly programming background, one thing I was wondering is whether it is possible in Javascript to detour a function, meaning, replacing it with a function that I defined and then call the original one, to add additional code or hook that function.
I already found examples, but all of them are not what I would qualify clean, involve creating additional variables, etc

Share Improve this question asked Oct 23, 2018 at 9:31 user10545192user10545192
Add a comment  | 

1 Answer 1

Reset to default 25

Monkey patching in Javascript is used heavily by many frameworks jusk like zone.js patch async operations (For angular).

Solution 1: Simplest way monkey patching can be used is as follows.

var orig_setTimeout = window.setTimeout;

window.setTimeout = function setTimeout(fn, ms) {
    // your patching code goes here
    return orig_setTimeout(fn, ms);
}

Solution 2: Using IIFE.

Credit @Annihil link

function originalFn(arg){
    return console.log("originalFn is invoked with argument: " + arg);
}

var patchedFn = (function(originalFunction) {

    return function(){
        console.log("patched function is invoked with arguments: " + arguments)
        return originalFunction.apply(this, arguments);
    }
}(originalFn))


patchedFn("Hello");

// Above invocation will results in 
patched function is invoked with arguments: Hello
originalFn is invoked with argument: Hello

Solution 3: You can use apply trap of ES6 Proxies

var patchedFn = {
  apply (target, ctx, args) {
    console.log("patched function is invoked with arguments: " + args)
    return Reflect.apply(...arguments)
  }
}
function originalFn (arg) {
    return console.log("originalFn is invoked with argument: " + arg);
}
var proxyFn = new Proxy(originalFn, patchedFn);

// Now proxy function can be invoked as following

proxyFn("Hello");
proxyFn(...["Hello"]);
proxyFn.call(null, "Hello");
proxyFn.apply(null, ["Hello"]);

// All the above invocation will print the below output

patched function is invoked with arguments: Hello
originalFn is invoked with argument: Hello

Solution 4: You can also look into ES6 decorators. They might also suits your purpose. For a introduction to ES6 decorators you can follow the sitepoint

Case Study: If you wanted to understand how zone.js patched async operations please go through the blog post monkey patching in zone.js

发布评论

评论列表(0)

  1. 暂无评论