1

The small demo below illustrates my problem:

// 1 - Define a global reference to classA
(function() {
    window.classA = new ClassA();
})();

// 2 - ClassA object definition
function ClassA() {
    this.test1 = function() {
        document.write('test1');
    };
}

// 3 - ClassA inherits Array and has a test function
ClassA.prototype = new Array;
ClassA.prototype.test2 = function() {
    document.write(this[0]);
}

// 4 - Test our ClassA
var c = new ClassA();
c.test1();
c.push('test2');
c.test2();

// 5 - Test our global ClassA
classA.test1();
classA.push('test2'); // doesn't work
classA.test2(); // doesn't work

Try it here: http://jsfiddle.net/SPSW4/

What is the proper way to define a global variable classA (ClassA instance)?

4
  • you mean global as in static? did you consider reordering of your function calls? Commented Sep 3, 2011 at 14:36
  • global variable (an instance of ClassA) Commented Sep 3, 2011 at 14:40
  • there are no classes in JavaScript and naming a function class makes no sense. This makes it very confusing to read. Please reconsider your naming convention ;) Commented Sep 3, 2011 at 14:43
  • simply an example, please pay no attention to the names :) Commented Sep 3, 2011 at 14:49

6 Answers 6

2

The correct approach would be to create the pseudo-sub-classed Array constructor within an immediately invoked function expression and then expose the result to an explicit global object.

(function( global ) {
    // Declare the ArrayLike constructor
    function ArrayLike() {
        var args = [].slice.call( arguments ), 
            length = args.length, i = 0;

        this.length = length;

        for ( ; i < length; i++ ) {
            this[ i ] = args[ i ];
        }
        return this;
    }
    // Define ArrayLike's prototype by creating a new Array instance
    ArrayLike.prototype = new Array();

    // Define your own proto method
    ArrayLike.prototype.firstChar = function() {
        var ret = [], 
            length = this.length, i = 0;

        for ( ; i < length; i++ ) {
            ret[ i ] = this[ i ][ 0 ];
        }
        return ret;
    };
    // Expose the ArrayLike constructor.
    global.ArrayLike = ArrayLike;
})( this );

var a = new ArrayLike( "alpha", "beta", "gamma" );

console.log( a.push("delta") ) // 4
console.log( a ); // ["alpha", "beta", "gamma", "delta"]
console.log( a.firstChar() ); // ["a", "b", "g", "d"]

See it live: http://jsfiddle.net/rwaldron/gLdkb/

Sign up to request clarification or add additional context in comments.

Comments

1

Your code appears to be binding the global classA variable before ClassA is fully defined. I believe you will have more luck if you do it like:

// 1 - define ClassA 
window.ClassA = function() {
    this.test1 = function() {
        document.write('test1');
    };
};
ClassA.prototype = new Array;
ClassA.prototype.test2 = function() {
    document.write(this[0]);
}

// 2 - Define a global reference to classA
window.classA = new ClassA();

// 3 - Test our ClassA
var c = new ClassA();
c.test1();
c.push('test2');
c.test2();

// 4 - Test our global ClassA
classA.test1();
classA.push('test2'); // doesn't work
classA.test2(); // doesn't work

Here's an example: http://jsfiddle.net/SPSW4/2/

7 Comments

Close but 'window.classA = new ClassA();' would have an influence on the order of my javascript right?
I'm not sure what you're asking, exactly. But window.classA = new ClassA(); just needs to occur after you are done configuring ClassA.
Not exactly true, but mainly. As you see by my answer, only the prototypes need to come before the assignment. That is because prototype methods are applied to objects that use the new keyword. Since those methods aren't attached at the time of ... = new ClassA() the object doesn't see them.
In my answer I did ClassA.prototype = Array.prototype;, but here you do ClassA.prototype = new Array;. Is there any diference?
@Mario - I think the way you did it is better, or at least more closely following commonplace JavaScript coding conventions. I just kept the code that was being used in the original post, since it seemed to work anyways. Although if you just set ClassA.prototype = Array.prototype then won't adding a new method to ClassA also cause that new method to appear in Array? Perhaps using new Array avoids that issue?
|
0

swap

// 2 - ClassA object definition
function ClassA() {
    this.test1 = function() {
        document.write('test1');
    };
}

// 1 - Define a global reference to classA
(function() {
    window.classA = new ClassA();
})();

declaration before calling functions in JavaScript, it is a scripting language.

1 Comment

you're missing a semi-colon on test2 defintion - see my answer
0

Try this:

// 2 - ClassA object definition
function ClassA() {
    this.test1 = function() {
        document.write('test1');
    };
}


// 3 - ClassA inherits Array and has a test function
ClassA.prototype = new Array;
ClassA.prototype.test2 = function() {
    document.write(this[0]);
}

// 4 - Test our ClassA
var c = new ClassA();
c.test1();
c.push('test2');
c.test2();

// 1 - Define a global reference to classA
window.classA = new ClassA();

// 5 - Test our global ClassA
classA.test1();
classA.push('test2');
classA.test2();

Actually there were two problems: 1. Creating object before declaring class 2. Creating object before extending class

3 Comments

Same as with aroth's solution, this would influence the order of the javascript files. The function call technique should prevent that... but how to put it all together.
If you have this happening in different files, then you should say so in your question. Regardless, the solution is still the same. You just have to do something that ensures that you don't try to call new ClassA() until after ClassA is fully defined. A reasonable way to do this is to move the window.classA = new ClassA(); part so that it is at the very end of the file that defines ClassA.
If I understand you correctly Zyphrax you can do something like that at each of your files: if (typeof(classA) === 'undefined') window.classA = new ClassA();. Ugly but will work.
0

Define your class

ClassA = function()
{
    this.test1 = function()
    {
        document.write('test1');
    };
};

Then apply array prototype

ClassA.prototype = Array.prototype;

Then you can extend your class

ClassA.prototype.test2 = function()
{
    document.write(this[0]);
};

About the “global reference” part. In the first part of your code your are not making a reference, you are instancing a class which has not been defined yet at that point. There is no need to do that also. What is your point with that part?

Comments

0


  1. Move the class definition before the call.

    Note: The only thing that really needs to come first is the prototyping, since your code first assigns the class, but never sees the effect of the prototyping, which occurs later. Your class assignment should come after the prototypes.

  2. You're missing a ; after the test2() definition.


// Class Definition
function ClassA() {
   this.test1 = function() { document.write('foo'); };
}
   ClassA.prototype       = new Array();
   ClassA.prototype.test2 = function() { document.write(this[0]); };


// Init
(function() { 
   window.classA = new ClassA(); 
})();

// Method Calls
var c = new ClassA();
    c.test1();
    c.push('bar');
    c.test2();

classA.test1();
classA.push('bar');
classA.test2();

Comments

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.