Praveen Prasad
Praveen Prasad

Reputation: 32107

JavaScript context

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

Answers (6)

Russ Cam
Russ Cam

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

Carlos Lima
Carlos Lima

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:

Scope in JavaScript

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

Terje
Terje

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

Jordan S. Jones
Jordan S. Jones

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

MillsJROSS
MillsJROSS

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

Jarrett Widman
Jarrett Widman

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

Related Questions