Я у себя использую подобный скрипт для вмешательства в чужой код(пример конкретно с ajax):
function waitFor(obj, ...props){
var callback = props.pop();
function isPrimitive(obj){
return !["function", "object"].includes(typeof obj);
}
function next(obj, prop){
if(props.length) return defineSetter(obj[prop], props.shift());
callback(obj, prop);
}
function defineSetter(obj, prop){
if(isPrimitive(obj))
return console.error(`Object needed. Can not wait for property "${prop}" in primitive "${obj}".`);
if(prop in obj) return next(obj, prop);
Object.defineProperty(obj, prop, {
enumerable: false,
configurable: true,
set: function(value) {
delete obj[prop];
obj[prop] = value;
next(obj, prop);
}
})
}
if(isPrimitive(obj))
return console.error(`Object needed. Can not wait for properties in primitive "${obj}".`);
if(!props.length)
return console.error('No properties to wait was specified.');
defineSetter(obj, props.shift());
}
function decorate(func, callback){
var out = function(){
return func.apply(this, callback.apply(this, arguments) || arguments)
};
out.prototype = Object.create(func.prototype);
return out;
}
function replace(text){
return [
text.replace(/foo/g, 'bar') //заменяем в полученном ajax ответе foo на bar
];
}
waitFor(unsafeWindow, '$', 'ajax', function($, ajax){ //ждём пока подгрузится $.ajax
$.ajax = decorate($.ajax, function(options){ //подменяем $.ajax
if(options && options.url ) console.log(url); //логируем url запроса
if(options && options.success && options.url && options.url.startsWith('/some/'))
options.success = decorate(options.success, replace); //подменяем коллбэк для запросов на url начинающихся с "/some/"
});
})
Писано на коленке, так что можно наверное красивей и лучше, но "работает и не трогаю".)