Могу ли я перехватить функцию, вызванную напрямую?
В этом коде я создал функцию, называемую someFunction. Затем я изменил функции Function.prototype.apply и call. Поэтому вместо того, чтобы работать с моим функциональным кодом, я запускаю свой код перехвата (который показывает предупреждение). Но ни "вызов", ни "применение" не перехватывают прямой вызов метода. Можно ли перехватить это?
Function.prototype.call = function(){alert("call");};
Function.prototype.apply = function(){alert("apply");};
function someFunction(){}
window.onload = function(){
someFunction.call(this); //call alert is shown
someFunction.apply(this); //apply alert is shown
someFunction(); //how can I intercept this?
}
Ответы
Ответ 1
Вы можете только переопределить известную функцию, установив для нее другую функцию (например, вы не можете перехватить ВСЕ вызовы функций):
(function () {
// An anonymous function wrapper helps you keep oldSomeFunction private
var oldSomeFunction = someFunction;
someFunction = function () {
alert("intercepted!");
oldSomeFunction();
}
})();
Обратите внимание, что если someFunction
уже был псевдоним/ссылка другим script, прежде чем он был изменен этим кодом, эти ссылки будут по-прежнему указывать на то, что исходная функция не будет переопределяться функцией замены.
Ответ 2
Function.prototype.callWithIntercept = function () {
alert("intercept");
return this.apply(null, arguments);
};
var num = parseInt.callWithIntercept("100px", 10);
Стоит отметить, что в более новых версиях JS есть объекты Proxy
, которые вы можете использовать:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Ответ 3
Есть возможность перехватить прямой вызов функции. Для этого требуется:
- Либо функция создается функцией .prototype.bind, и перед созданием функции вам необходимо перезаписать Function.prototype.bind или
- Функция создается из функции() (или новой функции()), и вы также должны перезаписать функцию Function перед созданием целевой функции.
Если ни один из вышеперечисленных двух не может быть выполнен, единственный способ перехвата прямого вызова - обернуть целевую функцию, которая является решением, предоставленным AndyE fooobar.com/questions/243422/...
Для функции, созданной литералом функции и скрытой в частной области, нет способа перехватить прямой вызов.
У меня есть запись в блоге: http://nealxyc.wordpress.com/2013/11/25/intercepting-javascript-function/
Ответ 4
Вы можете выполнять итерацию по глобальной области и заменять любые объекты типа функции, которые вы не находите "ваши".