0

This is an example from JavaScript:The Definitive Guide by David Flanagan

//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) {
  var original = o[m];                            // Remember original method in the closure.
  o[m] = function() {                             // Now define the new method.
    console.log(new Date(), "Entering:", m);      // Log message.
    var result = original.apply(this, arguments); // Invoke original.
    console.log(new Date(), "Exiting:", m);       // Log message.
    return result;                                // Return result.
  };
}

I understand that since m is a method of o, 'this' should refer to the object o. But I cannot understand how; because in a function 'this' should refer to the global object (non-strict mode).
Also, how does the 'arguments' array contain the original function's arguments and not of the anonymous wrapper function's?

Abhimanyu Pathania
  • 335
  • 2
  • 7
  • 18
  • It is impossible to say. The value of `this` depends on how the function is called and you don't show us how you call `o[m]`. The statement *in a function 'this' should refer to the global object (non-strict mode)* is only true sometimes (since the value depends on how it is called, and it may or may not be called in the context of the global object). – Quentin Nov 15 '14 at 16:30
  • @Quentin Yes, you are correct. I realized it afer reading [this](http://stackoverflow.com/questions/3127429/javascript-this-keyword) answer. I think the author intends to call the function 'm' as a method to object 'o' in the global context. – Abhimanyu Pathania Nov 15 '14 at 16:54
  • @Quentin: It's not at all impossible, as the value of `this` actually is irrelevant. It's just passed on to the original method, so that it will be called with the same context as the wrapper function. – Guffa Nov 19 '14 at 08:32

1 Answers1

-1

The trace function will replace a method in an object with a wrapper, which will output some log meddages and call the original method.

The anonymous function is the wrapper that will be called instead of the original method. When it is called, it's called as a method of the object, so this will refer to the object.

Note that the anonymous function isn't executed in the trace function. It replaces the original method, so it will be called later on when the original method would have been called.

The arguments array is the arguments of the wrapper function, so that will be the arguments that was intended for the original method. That's why they are passed along when the original method is called.

If you have an object like this:

var html = {
  bold: function(x) {
    return "<strong>" + x + "</strong>";
  }
};

If you now use the trace function:

trace(html, 'bold');

Now the html object will contain the equivalent of:

{
  bold: function() {
    var m = 'bold';
    var original = function(x) {
      return "<strong>" + x + "</strong>";
    };
    console.log(new Date(), "Entering:", m);
    var result = original.apply(this, arguments);
    console.log(new Date(), "Exiting:", m);
    return result;
  }
}
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • Why the downvote? If you don't explain what it is that you think is wrong, it can't improve the answer. – Guffa Nov 19 '14 at 08:28