Имея низкий уровень программирования C/assembly, мне было интересно, возможно ли в Javascript обходить функцию, то есть заменять ее на функцию, которую я определил, а затем вызвать исходную, добавить дополнительный код или зацепить эта функция.
Я уже нашел примеры, но все они не то, что я бы квалифицировал как чистый, включал создание дополнительных переменных и т.д.
Патч обезьяны в Javascript широко используется многими фреймворками jusk, такими как операции async для патчей zone.js (для угловых).
Решение 1. Можно использовать простейший способ обезвреживания обезьяны.
var orig_setTimeout = window.setTimeout;
window.setTimeout = function setTimeout(fn, ms) {
// your patching code goes here
return orig_setTimeout(fn, ms);
}
Решение 2. Использование IIFE.
Кредит @Annihil ссылка
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
Решение 3. Вы можете использовать ловушку приложений 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
Решение 4. Вы также можете посмотреть декораторы ES6. Они могут также соответствовать вашей цели. Для введения в ES6 декораторы вы можете следить за Sitepoint
Пример: если вы хотите понять, как zone.js исправили асинхронные операции, пройдите через патч обезьяны блога post в zone.js