Question 1
For your first question, let's simplify the example so it's clear what being done:
function bind(func, thisArg) {
return function () {
return func.apply(thisArg, arguments);
};
}
What happens here is that a closure is created that allows the access of the original function and the value of this
that is passed. The anonymous function returned will keep the original function in its scope, which ends up being like the following:
var func = function () {};
var thisArg = {};
func.apply(thisArg, [/*arguments*/]);
About your issue with arguments
, that variable is implicitly defined in the scope of all functions created, so therefore the inner arguments
will shadow the outer arguments
, making it work as expected.
Question 2
Your problem is to your misunderstanding of the late binding of this
-- this is one of the more confusing things about JavaScript to people used to more object-oriented languages that also have their own this
keyword. The value of this
is only set when it is called, and where it is called defines the value of this
when it is called. It is simply the value of the parent object from where it is at the time the function is called, with the exception of cases where the this
value is overridden.
For example, see this:
function a() {return this;};
a(); // global object;
var b = {};
b.a = a;
b.a(); // object b
If this
was set when the function was defined, calling b.a
would result in the global object, not the b
object. Let's also simplify what happens with the second function given:
function trace(obj, property) {
var method = obj[property]; // Remember original method in the closure.
obj[property] = function () { // Now define the new method.
console.log(1); // Log message.
// Invoke original method and return its result
return original.apply(this, arguments);
};
}
What happens in this case is that the original method is stored in a closure. Assigning to the object that the method was originally in does not overwrite the method
object. Just like a normal method assignment, the principles of the this
value still work the same -- it will return the parent object, not the function that you've defined. If you do a simple assignment:
var obj = {};
obj.foo = function () { return this; };
obj.foo(); // obj
It does what was expected, returns the parent object at the time of calling. Placing your code in a nested function makes no difference in this regard.
Some good resources
If you'd like to learn more about writing code in JavaScript, I'd highly recommend taking a look at Fully Understanding the this
Keyword by Cody Lindley -- it goes into much more detail about how the this
keyword behaves in different contexts and the things you can do with it.