Как я могу чисто обезьяна исправить функцию в Javascript?

1

Имея низкий уровень программирования C/assembly, мне было интересно, возможно ли в Javascript обходить функцию, то есть заменять ее на функцию, которую я определил, а затем вызвать исходную, добавить дополнительный код или зацепить эта функция.
Я уже нашел примеры, но все они не то, что я бы квалифицировал как чистый, включал создание дополнительных переменных и т.д.

Теги:

1 ответ

1
Лучший ответ

Патч обезьяны в 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

  • 0
    Спасибо, но ваш пример включает создание временной переменной для хранения исходной функции указателя, я не хочу обременять ее текущей областью видимости ...
  • 3
    В этом случае используйте прокси ES6. Вы можете использовать «применить» ловушку для следующего. Более подробную информацию можно найти на ponyfoo.com/articles/es6-proxy-traps-in-depth#apply
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню