At some point you should trust what is available in the window. This either means caching the features you plan to use, or trying to isolate your code.
A βsimpleβ solution to calling call is to temporarily set the property:
var safeCall = (function (call, id) { return function (fn, ctx) { var ret, args, i; args = [];
Then it can be used as:
safeCall(fn, ctx, ...params);
Remember that parameters passed to safeCall will be combined into an array. You will need to apply to make this behave properly, and I'm just trying to simplify the dependencies here.
An improved version of safeCall that adds an add dependency:
var safeCall = (function (call, apply, id) { return function (fn, ctx) { var ret, args, i; args = []; for (i = 2; i < arguments.length; i++) { args.push(arguments[i]); } apply[id] = call; ret = apply[id](fn, ctx, args); delete apply[id]; return ret; }; }(Function.prototype.call, Function.prototype.apply, (''+Math.random()).slice(2)));
This can be used as:
safeCall(fn, ctx, ...params);
An alternative solution to calling safely is to use functions from a different window context.
You can do this by simply creating a new iframe function and capture in your window. You still have to assume some dependence on the DOM manipulation functions available, but this happens as an installation step, so any future changes will not affect the existing script:
var sandboxCall = (function () { var sandbox, call;
Then it can be used as:
sandboxCall.call(fn, ctx, ...params);
Both safeCall and sandboxCall safe from future changes to Function.prototype.call , but as you can see, they rely on some existing global functions to work at runtime. If a malicious script executes before this code, your code will still be vulnerable.