You can overwrite .getJSON with your own method.
The native getJSON method can be seen here:
https://j11y.io/jquery/#v=git&fn=jQuery.getJSON
function (url, data, callback) {
return jQuery.get(url, data, callback, "json");
}
It's a simple enough matter to take the callback passed to getJSON, pass your own callback to jQuery.get with 'text' instead of 'json', parse the JSON using the custom reviver, and then call the original callback.
A complication is that the second parameter passed to getJSON is optional (data to send with the request).
Assuming that you always use a success function (third and last argument), you can use rest parameters and pop() to get the passed success function. Create a custom success function that takes the text response and uses the custom JSON.parse, then calls the passed success function with the created object.
const dequoteDigits = json => JSON.parse(
json,
(key, val) => (
typeof val === 'string' && /^[+-]?[0-9]+(?:\.[0-9]+)$/.test(val)
? Number(val)
: val
)
);
jQuery.getJSON = function (url, ...rest) {
// normal parameters: url, data (optional), success
const success = rest.pop();
const customSuccess = function(textResponse, status, jqXHR) {
const obj = dequoteDigits(textResponse);
success.call(this, obj, status, jqXHR);
};
// spread the possibly-empty empty array "rest" to put "data" into argument list
return jQuery.get(url, ...rest, customSuccess, 'text');
};
jQuery.getJSON('https://jsonplaceholder.typicode.com/users', (obj) => {
console.log(obj);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
The difference in the snippet output above vs the URL requested
https://jsonplaceholder.typicode.com/users
is that the latitude and longitude property values have been transformed into numbers, rather than remaining strings.
If you ever use await as well without a success callback, then you'll need to overwrite the then property of the returned Promise, though dealing with the optional success callback makes the code's logic a lot uglier:
const dequoteDigits = json => JSON.parse(
json,
(key, val) => (
typeof val === 'string' && /^[+-]?[0-9]+(?:\.[0-9]+)$/.test(val)
? Number(val)
: val
)
);
jQuery.getJSON = function (url, ...rest) {
// normal parameters: url, data (optional), success (optional)
const data = rest.length && typeof rest[0] !== 'function'
? [rest.shift()]
: [];
const newSuccessArr = typeof rest[0] === 'function'
? [function(textResponse, status, jqXHR) {
const obj = dequoteDigits(textResponse);
rest[0].call(this, obj, status, jqXHR);
}
]
: [];
// spread the possibly-empty dataObj and newSuccessObj into the new argument list array
const newArgs = [url, ...data, ...newSuccessArr, 'text'];
const prom = jQuery.get.apply(this, newArgs);
const nativeThen = prom.then;
prom.then = function(resolve) {
nativeThen.call(this)
.then((res) => {
const obj = dequoteDigits(this.responseText);
resolve(obj);
});
};
return prom;
};
jQuery.getJSON('https://jsonplaceholder.typicode.com/users', (obj) => {
console.log(obj[0].address.geo);
});
(async () => {
const obj = await jQuery.getJSON('https://jsonplaceholder.typicode.com/users');
console.log(obj[0].address.geo);
// console.log(obj);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>