1

Sorry for the title, but it's really hard to put a title on this issue (feel free to suggest a better one).

My issue is best explained via this JsFiddle: http://jsfiddle.net/ryLhcn4q/2/

CS = {};

CS.OverviewController = {
    foo: "bar",

    render: function() {
        console.log("Rendering. foo = " + this.foo);
    }    
};

CS.handleClick = function(callback) {
    console.log("handleClick");

    if (callback) {
        callback();
    }
};

$("button").click(function(e) {
    CS.handleClick(CS.OverviewController.render);
});

If you click on the button, the console indicates that the value of foo is undefined. How can I have the correct scope of this, so that the console indicates bar as the value for foo?

Blackbird
  • 2,288
  • 4
  • 23
  • 39
  • See the third question of the fun quiz on the link provided by @BenFortune to know what happened! – Kyll May 07 '15 at 09:22

2 Answers2

3

You should use

CS.handleClick(CS.OverviewController.render.bind(CS.OverviewController));

.bind defines the context of the function. Or in other words it sets its this object to something.

Your example doesn't work because you refer a function out of its context. The this points to the global scope (i.e. the window object). So:

window.foo = 'global';
$("button").click(function(e) {
    CS.handleClick(CS.OverviewController.render);
});

will output global -> jsfiddle

Krasimir
  • 12,605
  • 3
  • 34
  • 52
0

PFB the code, this will work

    CS = {};

CS.OverviewController = {
    foo: "foo",

    render: function() {
        console.log("rendering. foo = " + this.foo);
    }    
};

CS.handleClick = function(e, context, callback) {
    console.log("handleClick");

    if (callback) {
        context[callback]();
    }
};

$("button").click(function(e) {
    CS.handleClick(e, CS.OverviewController, 'render');
});

JsFiddleUpdated

You can also use "apply" or "call"

wallop
  • 2,243
  • 1
  • 19
  • 34