James
James

Reputation: 2860

Javascript doesn't thnk 'class' object has been defined

This has been bugging me for hours now. I have a file that has a Javascript class object defined then immediately after the definition, the clas is being instantiated. I am getting a not defined error as if the class is not defined when it quite clearly is:

(function($) {
function NewsSlider(element, children) {
    this.element = element;
    this.children = children;   
    this.currentItem  = 0;
    this.maxCount = this.children.length;
}

NewsSlider.prototype.displayItem = function() {
    this.children.hide();
    this.children[this.currentItem].show();
}

NewsSlider.prototype.startNewSlider = function() {
    if(this.currentItem > this.maxCount) {
        this.currentItem = 0;
    }
    setTimeout(function() {
        this.displayItem();
    }, 5000);
}
})(jQuery);

var a = new NewsSlider();

Here is the error I am getting:

ReferenceError: NewsSlider is not defined   

var newsSliders = new NewsSlider("#news-ticker ul", "#news-ticker ul li");

Now, I seem to see no problem in this code whatsoever and have done this many times before so can someone please point me out what is going wrong or where I am being stupid? Thanks

Upvotes: 0

Views: 54

Answers (3)

Halfpint
Halfpint

Reputation: 4079

You cannot expect it to "think" that the class has been defined if it has no clue about the object existing.

You have defined your class within a closure and therefore once you leave the scope of that function, jQuery no-longer has a reference to it and therefore you will get a Reference Error.

Consider:

--> function()
|   {
|       class aClass definition here
|
|       a = new aClass;
|
|       // do some work with the class here.
|
--> } 

Everything above here is fine as the class is accessible within the current scope, however consider the second example below where we try to assigned a value to p, outside the scope of the function containing the class definition:

--> function()
|   {
|       class aClass definition here
|
|       a = new aClass;
|
|       // do some work with the class here.
|
--> } 

var p = a.getParam();

A reference error will be thrown here as p is trying to get its value from a variable which cannot be found in the current scope, therefore a reference error is produced.

In order to solve this its best to have some global reference to your class.

Upvotes: 0

Patrick Gunderson
Patrick Gunderson

Reputation: 3281

This is a scope error, and is a result of putting your code within a closure. This is actually a feature of closures and precisely why you are supposed to use them. So you CAN'T access the variables defined within. This is to prevent pollution of the global namespace.

You can define NewsSlider outside of your closure, you can return NewsSlider from your closure and assign it to a new var, or you can eliminate the closure all together.

Option 1:

var NewsSlider;

(function($) {
NewsSlider = function(element, children) {
    this.element = element;
    this.children = children;   
    this.currentItem  = 0;
    this.maxCount = this.children.length;
}
})(jQuery);

var a = new NewsSlider();

Option 2:

var NewsSlider = (function($) {
    var NewsSlider = function(element, children) {
        this.element = element;
        this.children = children;   
        this.currentItem  = 0;
        this.maxCount = this.children.length;
    }
    return NewsSlider;
})(jQuery);

var a = new NewsSlider();

Option 3:

function NewsSlider(element, children) {
    this.element = element;
    this.children = children;   
    this.currentItem  = 0;
    this.maxCount = this.children.length;
}

var a = new NewsSlider();

Upvotes: 2

Quentin
Quentin

Reputation: 943142

You have declared NewsSlider inside another function, so it is scoped to that function.

You are trying to use it outside the function where it doesn't exist.

Move function NewsSlider(element, children) { ... } outside the anonymous function or move var a = new NewsSlider(); inside it.

Since you don't use jQuery or create any top level scope variables other than NewsSlider, you might as well get right of the anonymous function entirely.

Upvotes: 4

Related Questions