views:

51

answers:

2

I am getting a "TestFunc is not defined" error when this bit of code...

/* my_object.js */
"use strict";
function MyObject (param) {
    this.param = param;
}

MyObject.prototype.TestFunc = function () {
    console.log ('in TestFunc');
}

MyObject.prototype.RealFunc = function () {
    // I have tried 3 different ways to call TestFunc:
    // 1.
    this.TestFunc ();

    // 2.
    TestFunc ();

    // 3. (I didn't really think this would work,
    //     but thought it was worth a try...)
    MyObject.TestFunc ();
}

...gets run from this bit of code:

/* index.js */
var myObj = new MyObject ('test');
myObj.RealFunc (); // Firebug: "TestFunc is not defined"
+1  A: 
// 1.
this.TestFunc ();

That's fine. That'll work, with the other calls removed.

(Well, it works as long as you don't peel off the RealFunc from its owner and call it on its own, like var method= myObj.RealFunc; method(); or via an event handler or timeout. In that case this in RealFunc wouldn't be the MyObject instance and you'd need to look at closures or Function.bind to get it to work.)

// 2.
TestFunc ();

Nope, TestFunc is not defined as a variable in local or global scope. This causes the error you get from Firebug.

// 3. (I didn't really think this would work,
//     but thought it was worth a try...)
MyObject.TestFunc ();

No, you were right. :-) It would be MyObject.prototype.TestFunc.call(this), done explicitly.

JavaScript does kind of confuse the matter by putting some of the same methods on the standard constructor functions for built-in objects as on their prototypes (for example String.split exists where really only String.prototype.split should). But that doesn't happen to your own objects unless you explicitly say something like MyObject.TextFunc= MyObject.prototype.TextFunc.

bobince
ah ha! i didn't include it in the above simplified version, since i totally forgot about what happens to 'this' in an eventhandler, but RealFunc () is indeed an event handler...
W_P
Yeah, I suspected as much... the way method-binding and `this` works in JavaScript is very strange compared to other programming languages; it's probably the most common gotcha.
bobince
+1  A: 

Variant 1 seems correct. I tried your code in ExecuteJS and skipped 2. and 3., it worked (although I removed the call to console.log and changed it to alert). TestFunc is called within RealFunc.

What happens if you remove "use strict";?

GodsBoss
ECMAScript Fifth Edition's 'use strict' won't do anything... yet. I look forward to browsers being released where it does, though!
bobince