Reputation: 393
This is the code which I got stuck on.
var bind = function(func, thisValue) {
return function() {
return func.apply(thisValue, arguments);
}
}
I've been learning about execution contexts and closures. My guess is that the function in the first return statement is a function expression as it's part of a statement. However, then I don't know how a closure, with reference to func and thisValue, is created.
If it is a function expression, then when bind is called, the anonymous function won't be evaluated there and then and therefore won't have a function object set up with a [[scope]] property containing the scope of bind's execution context. And so, the anonymous function won't have access to func and thisValue through it's [[scope]] property.
So if the code does indeed form a closure, then my guess is wrong and the function in the first return statement must be a function declaration. Or maybe I'm misunderstanding when return is evaluated? Any help on this would be greatly appreciated!
Upvotes: 3
Views: 151
Reputation: 393
So I did some digging in the ECMAScript Language Specification and came to the conclusion that the anonymous function that's being returned is a function expression... and it really seems quite simple now. When defining a function using a function declaration, the identifier isn't optional and so an anonymous function can't be defined using a function declaration. Anonymous functions can only be defined using function expressions because with function expressions, the identifier is optional.
I also said this...
If it is a function expression, then when bind is called, the anonymous function won't be evaluated there and then and therefore won't have a function object set up with a [[scope]] property containing the scope of bind's execution context.
I was wrong. The function expression is evaluated when bind() returns. Therefore, a function object is set up for it and everything is scoped as it should be.
I hope I've made some sense. If I've missed anything, please comment!
Upvotes: 2
Reputation: 57719
This seem quite complicated but is actually very simple. What this function does is return a function where the arguments you pass are bound to thisValue
.
Here is an example:
var bind = function(func, thisValue) {
return function() {
return func.apply(thisValue, arguments);
}
}
var x = {
"key": "the value"
};
var y = {
"key": "the y value"
};
function alert_key() {
alert(this.key);
}
var bound_function = bind(alert_key, x);
bound_function(); // alerts "the value"
var bound_function2 = bind(alert_key, y);
bound_function2(); // alerts "the y value"
It's important to realize that this
in this.key
is bound to x
because it is the first argument in func.apply(thisValue, arguments)
arguments
is a magic JavaScript variable that will contain all arguments passed to the function. So func.apply(thisValue, arguments)
really only just passes all arguments along but set the this
context to thisValue
(or x
and y
in my example).
Example for extra argument(s):
var bind = function(func, thisValue) {
return function() {
return func.apply(thisValue, arguments);
}
}
var x = {
"key": "the value"
};
function alert_key(another_value) {
alert(this.key + " " + another_value);
}
var bound_function = bind(alert_key, x);
bound_function("another value"); // alerts "the value another value"
bound_function("value y"); // alerts "the value value y"
Upvotes: 1