Question

I'm writing a display class in Javascript (using jQuery) which may be instantiated before a web page has loaded. If the page isn't ready when the constructor is called, the instance is added to a static instances field for the class, which is iterated over when the page has loaded:

function MemDisplay(ready_callback) {
    this.readyCallback = ready_callback;
    if (MemDisplay.ready) {
        this.linkToPage();
    } else {
        MemDislay.instances.push(this);
    }
}

//this makes sure that the ready callback can be sent when the page has loaded
MemDisplay.ready = false;
MemDisplay.instances = [];

$(document).ready(function () {
    var i;

    MemDisplay.ready = true;
    for (i = 0; i < MemDisplay.instances.length; i += 1) {
        MemDisplay.instances[i].linkToPage();
    } });

//example truncated for brevity

When I run this through JSLint, I get this error:

Problem at line 25 character 9: 'MemDislay' is not defined.

MemDislay.instances.push(this);

I need to reference MemDisplay.instances in the constructor, but the constructor is where MemDisplay is defined, so I'm puzzled about how to make this work while fitting within JSLint's guidelines. Is there a better way to do this? Should I just ignore JSLint in this instance?

Was it helpful?

Solution 2

My brain must have figured this out while I slept: the trick is to attach the field to the prototype, which seems pretty obvious now that I've thought of it, since that's what you have to do to define class methods.

The following checks out in JSLint, and demonstrates the sharing of a field between all instances of MyClass (or see this code on jsfiddle):

/*global alert */

function MyClass(name) {
    this.name = name;
    MyClass.prototype.field += 1;
}

MyClass.prototype.field = 0;

MyClass.prototype.myMethod = function () {
    alert(this.name + "'s class's field is " + MyClass.prototype.field);
};

var myObj = new MyClass("first");
myObj.myMethod();

var myOtherObj = new MyClass("second");
myObj.myMethod();
myOtherObj.myMethod();

I'm not sure if there's a prettier way to do it, as having 'prototype' all over the place feels a bit excessive, on the other hand it could be a good thing because it makes it clear that prototype.field does not belong to the instance.

OTHER TIPS

JSLint here is actually highlighting a broader issue with the code without saying so.

You are referencing a class (MemDisplay) but never instantiating it as an object. I.e. you are treating the class like an already-instantiated object.

I've created a very simple equivalent to what you are trying to achieve (also at this JSFiddle)

function MyClass(p1, p2){
    this.param1 = p1;   //class member/property - use this to access internally.
    if (this.param1 === 1){ //you might want to consider doing this as part of some setter method
        alert("test");
    }
    this.MyMethod = function(){ //class method/function
        alert("MyMethod Called");
    };
}

var myObj = new MyClass(1,2); //instantiate
alert(myObj.param1); //get value of object member (you can set as well)
myObj.MyMethod(); //call a method

It'll take a bit of reorgansiation, but by declaring the values up front, you can get make JSLint happy.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top