3

Can anyone axplain why the first thing works and the second dont?

function MyObj(val) {
    this.value = val;

    this.myFunc = function(selector) {
        $(selector).html("test: " + this.value);
    }
}

foo = new MyObj("tester");
foo.myFunc("#one"); //This works

func = foo.myFunc;
func("#two"); //This doesnt

How? and how can i make it work?

JSFIDDLE

2 Answers 2

4

A function’s this in JavaScript isn’t fixed to anything; when you call

something.somefunc()
// or something['somefunc']()

this gets bound to something. When you call a function without an object, this gets bound to undefined (in strict mode) or the global object.

You can get around it by keeping a variable to hold the right this:

function MyObj(val) {
    var obj = this;

    this.value = val;

    this.myFunc = function(selector) {
        $(selector).html("test: " + obj.value);
    };
}

ECMAScript 5 offers a method on Function.prototype specifically to deal with this (and you should generally put myFunc on MyObj.prototype, too):

var func = foo.myFunc.bind(foo);
func("#two"); // Works now
Sign up to request clarification or add additional context in comments.

4 Comments

LOL JavaScript will never stop trolling me, but Thanks :)
Using apply() or call() should also work when you pass foo: func.call(foo,'#two');
One minor detail, in strict mode this will be undefined. Not null.
@jaywalking101: Yikes, and on a recent answer, too! Thanks.
0

Use bind() to assign the value of this to a function:

function MyObj(val) {
    this.value = val;

    this.myFunc = function(selector) {
        console.log(this); // <--- look your console output
        $(selector).html("test: "+this.value);
    }
}

foo = new MyObj("tester");
foo.myFunc("#one");

func = foo.myFunc;
func.bind(foo)("#two"); //  <---- here

or:

func = foo.myFunc.bind(foo);
func("#two");

DEMO: http://jsfiddle.net/M8Qym/1/

3 Comments

Although literally doing func.bind(foo)("#two") should really just be func.call(foo, "#two").
the difference is that bind creates a new function, so he could use: func = foo.myFunc.bind(foo); and then just func("#two");
That’s why I said “literally” :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.