views:

191

answers:

4

Hi All,

why is this not ok?

aContract = function(){};
aContract.prototype = {
    someFunction: function() {
        alert('yo');
    },
    someOtherFunction: some$Other$Function
};

var some$Other$Function = function() {
    alert('Yo yo yo');
};

var c = new aContract();
c.someFunction();
c.someOtherFunction();

Firebug says c.someOtherFunction is not a function

But this works just fine

aContract = function(){};
aContract.prototype = {
    someFunction: function() {
        alert('yo');
    },
    someOtherFunction: some$Other$Function
};

function some$Other$Function() {
    alert('Yo yo yo');
};

var c = new aContract();
c.someFunction();
c.someOtherFunction();

What am I missing here??? I prefer to code in javascript using the first method, which usually works fine, but doesn't seem to work correctly when I prototype.

Thanks, ~ck in Sandy Eggo

+3  A: 

You have assigned some$Other$Function to aContract.prototype.someOtherFunction before you actually create some$Other$Function. The order of statements matters. If you switch the order of things you'll be good:

var some$Other$Function = function() {
    alert('Yo yo yo');
};

aContract = function(){};
aContract.prototype = {
    someFunction: function() {
        alert('yo');
    },
    someOtherFunction: some$Other$Function
};
John Kugelman
+4  A: 

At the time this is evaluated:

 aContract.prototype = { ... }

this has not yet been evaluated:

var some$Other$Function = function() { ... }

Thus aContract.prototype.someOtherFunction is set to undefined.

The reason the second works is because function declarations (which the second is, the first is an expression) are evaluated before any other statements. There are more details here: Named function expressions demystified

Miles
A: 

It appears that, in the global scope, var works differently than it does in function-local scopes. In function-local scopes, var-declared variables are lifted to the top of the function (i.e., any variable declared anywhere within a function with the keyword var is available anywhere else within that function). But in the global scope, perhaps only use of the keyword function to declare a variable yields the same result (i.e., that a variable declared with the keyword function will be available anywhere within that global scope, even in lines preceding that declaration).

Justice
That isn't true at all. Calling blah() displays "undefined": function blah() {alert(x); var x = 5; }
John Kugelman
That is not quite what happens. eg. (function(){var a = x + 1;var x = 2; return a;})() return NaN. You might be thinking more like (function(){var a = function(){return x + 1};var x = 2;return a()})()which does return 3.
BaroqueBobcat
+1  A: 

It's due to hoisting. Function statements are moved to the top of their scope.

Edit: Verification Crockford's JavaScript: The Good Parts page 113.

Nosredna