// Replace the method named m of the object o with a version that logs
// messages before and after invoking the original method.
function trace(o, m) {
// Remember original method in the closure
var original = o[m];
// Define the new method
o[m] = function() {
// Log message
console.log(new Date(), "Entering:", m);
// Invoke original
var result = original.apply(this, arguments);
// Log message
console.log(new Date(), "Exiting:", m);
return result;
};
}
Hello! The code example given above is from my coding book. It tries to illustrate a practice called “monkey-patching” using the apply
function in JavaScript. I'm really confused about the nature of the line where the original function is invoked:
var result = original.apply(this, arguments); // Invoke original.
As far as I understand, the call to the original function could also be written without the help of apply()
, since the thisarg is this
, which is to say that the execution context remains unchanged: the original
object.
The second point of confusion is where the hell the arguments
argument for apply()
comes from? Yes, I know that it is an object generated at every function invocation that is used to access the function arguments - but this line is inside an anonymous function without any arguments. I don't have a clue and am grateful for any hint.
Thank you in advance!
Your first question: Why is apply
necessary?
If you invoke original
directly in the anonymous function, this
inside original
is sure to refer to global
(undefined
in strict mode). The anonymous function, on the other hand, is declared as a method of o
, so if you invoke as o.m()
, this
inside the anonymous function should refer to o
. Passing o
to original
is desired because it preserved the semantic.
In addition to binding this
, apply
can also convert an array of arguments to individual parameters.
function toBeCalled(x,y){
console.log('x is: '+x+" y is:"+y)
}
function x (){
toBeCalled(arguments)
toBeCalled.apply(this,arguments)
}
x('aa','bb','vv')
//x is: [object Arguments] y is:undefined
//x is: aa y is:bb
See the difference?
Second question: Where is arguments
from?
In JavaScript, arguments
is a built-in variable within the scope of a function. The value of arguments
can only be determined when the function is invoked, it is not fixed at all.
function x (){
console.log(arguments)
}
x('aa','bb','vv')
x("ff","dd")
x(1123)
arguments
is assigned a value when x
is invoked, it is dynamic.