Reputation: 32107
var User = {
Name: "Some Name", Age: 26,
Show: function() { alert("Age= "+this.Age)};
};
function Test(fn) {
fn();
}
Test(User.Show);
===============
Alert shown by code is "Age= Undefined". I understand as User.Show function is called from inside of Test(), refers 'this' of 'Test()' function rather than 'User' object. My question is if there is any way to solve this problem?
Upvotes: 3
Views: 2319
Reputation: 125488
Another way using call()
var User = {
Name: "Some Name",
Age: 26,
Show: function() { alert("Age= "+this.Age);}
};
function Test(fn,obj) {
fn.call(obj);
}
Test(User.Show, User);
You may find John Resig's Learning Advanced JavaScript slideshow interesting, particularly the section on context
Upvotes: 1
Reputation: 4182
You could also do this:
Test(User.Show.bind(User));
Considering that to use the other suggestions you'd still have to pass the scope as the parameter, like:
function Test(fn, scope) {
fn.apply(scope || window);
}
Test(User.Show, User)
The alternative seems reasonable and easier.
Also, you might find this article interesting:
It explains the kind of issue you're facing as well as ways to get around it.
Much better than anything I could possibly write here as an answer :)
Upvotes: 2
Reputation: 1
var User = { Name: "Some Name", Age: 26, Show: function() { alert("Age= "+User.Age)} }; function Test(fn) { fn(); } Test(User.Show);
ps! refers 'this' of 'Test()' function rather than 'User'
No - in fact 'this' points to the window-object
Upvotes: 0
Reputation: 13883
One way to get it to execute on the scope of User
is to pass your Test
function a scope.
function Test(fn, scope) {
fn.apply(scope || window);
}
This will apply the passed function to the passed scope, or window if no scope was passed.
Test(User.Show, User)
would alert Age= 26
.
Upvotes: 5
Reputation: 1239
The way to solve this problem is to pass in the object you're scoping "this" to, inside of the Test function...
function Test(fn, scope, args) {
fn.apply(scope, args);
}
Test(User.Show, User, []);
Where the args array allows you to additionally pass in any arguments you may have. You could also leave the Test function as it is and just pass in an anonymous function...
Test(function() {User.Show()});
Upvotes: 7
Reputation: 6419
You have 2 mistakes. 1st is your semicolon should be moved inside of the } but the code should be function() { alert("Age= "+User.Age);}
if you want to call it the way you are and have it show the age.
Upvotes: 1