I'm modifying several functions of some "core" JS software using "hijacking":
var orig_func = func; // initially function(a,b,c,d)
func = function(a,b,c,d) {
// modify arguments
d = someCustomization(c,d);
// do additional stuff
doSomethingCustom(a);
// apply the original "core" function
return orig_func.apply(this,arguments);
}
which works nicely unless the modified params are optional: calling
func(a,b);
works in a way that d is undefined even though someCustomization returns something else when both its arguments are undefined.
Here's an MVCE for using in cosole:
var f = function(optionalParam){ if(optionalParam) console.log(optionalParam); };
var orig_f = f;
f = function(optionalParam){
optionalParam = optionalParam ? 'custom: '+optionalParam : 'default';
orig_f.apply(this, arguments);
};
f(); // shows undefined
f('test'); // shows 'custom: test'
"Expected" behaviour is to see "default" in console in the first case, but I get undefined instead.
After some experiments and using this thread where I've summarized adding a positioned param in a corresponding answer I've come with the following solution in terms of MCVE:
var f = function(some,optionalParam){
console.log('some:',some);
console.log('optionalParam:',optionalParam);
};
var orig_f = f;
f = function(some,optionalParam){
if(optionalParam)
optionalParam = 'custom: '+optionalParam;
else {
var argPosition = 2;
while(arguments.length < argPosition)
[].push.call(arguments,undefined);
arguments[argPosition-1] = 'default';
}
orig_f.apply(this, arguments);
};
f(); // shows 'some: undefined' and 'optionalParam: default'
or in terms of the initial task:
var orig_func = func; // initially function(a,b,c,d)
func = function(a,b,c,d) {
// modify arguments
while(arguments.length < 4)
[].push.call(arguments,undefined);
arguments[3] = someCustomization(c,d);
// do additional stuff
doSomethingCustom(a);
// apply the original "core" function
return orig_func.apply(this,arguments);
}
But I'm not really able to explain what's the problem with the initial approach: why it worked for required (used) params and failed for an optional (unused) one? Does it have anything to do with closures? Why d is "not connected" with arguments in the second case?
arguments, you just assign to the local variables? The "connection" to the arguments object is deprecated and only works in sloppy mode. Don't use that.