Ev Haus
Ev Haus

Reputation: 1654

Class loses "this" scope when calling prototype functions by reference

Can anyone explain to me why "b" returns undefined and how I can get around this problem? Why does the "this" scope get lost when I call prototype functions by reference?

MyClass = function(test) {
this.test = test;
}

MyClass.prototype.myfunc = function() {       
   return this.test;
}

var a = new MyClass('asd').myfunc();
var b = new MyClass('asd').myfunc;

// Returns "asd" correctly
console.log(a)

// Returns undefined??
console.log(b())

=== EDIT / SOLUTION ===

As plalx writes, the correct solution in my case is to use .bind(). So the result looks like this:

MyClass = function(test) {
    this.test = test;
}

MyClass.prototype.myfunc = function() {       
   return this.test;
}

var a = new MyClass('asd').myfunc();
var b = new MyClass('asd'),
    bfunc = b.myfunc.bind(b)

// Returns "asd" correctly
console.log(a)

// Also returns "asd" correctly!
console.log(bfunc())

Upvotes: 2

Views: 1872

Answers (3)

Alan Kis
Alan Kis

Reputation: 1910

Here you are assigning to a variable a result of myfunc() function.

var a = new MyClass('asd').myfunc();

And here, you are asigning to b variable function reference, rather then runing it, and assign result to variable.

var b = new MyClass('asd').myfunc;

And finaly here:

console.log(b())

You trying to log result of function b and in that case b() isn't defined anywhere, only it is assigned reference to function.

Try this:

console.log(b); // It logs [Function]

But besides that, your question is hard to understand.

P.S. Use semicolons!

Upvotes: -1

plalx
plalx

Reputation: 43748

You need to explicitely bind the this value if you want this behaviour.

var c = new MyClass('asd'),
    b = c.myfunc.bind(c);


console.log(b());

By default, this will point to the leftSide.ofTheDot(); in an invocation, or simply the object on which the function was called.

Note: Calling b(); is the same as window.b();.

Binding every function to the object instance is possible but rather inefficient because functions will not get shared across instances anymore.

E.g.

function MyClass(someVal) {
    var me = this;

    me.someVal = someVal;

    me.someFn = function () {
        return me.someVal;
    };
}

Upvotes: 6

wootscootinboogie
wootscootinboogie

Reputation: 8705

The line var b... is a function reference and you're not actually calling the function.

Upvotes: -1

Related Questions