1

I want an array of objects to monitor (loading of) each span element (using XMLHTTPRequest to retrieve a URL on another page and place into the relevant span - I haven't included this functionality below as I'm only interested in the object array).

I liked the idea of the following (Doug Crockford?) snippet, but I just can't get it to work. I get:

URLLoad.LoadingTxt000003.SetLoadTimeout is not a function

Any ideas?

Here's my code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>

<script language="javascript" type="text/javascript">

function URLLoad(id) {
    alert(id);

    return URLLoad[id] = {
        Tagid:id,
        LoadTimeout:0
    }
}

URLLoad.prototype.SetLoadTimeout = function(lt) {
    this.LoadTimeout = lt;
}

URLLoad("LoadingTxt000003");
URLLoad("LoadingTxt000005");

alert(URLLoad.LoadingTxt000003.DelayTimeout + URLLoad.LoadingTxt000005.DelayTimeout);

URLLoad['LoadingTxt000003'].SetLoadTimeout(20); //doesn't work
URLLoad.LoadingTxt000003.SetLoadTimeout(20);    //doesn't work

</script>

</head>

<body>

    <span id="LoadingTxt000003">...</span>
    <span id="LoadingTxt000005">...</span>

</body>
</html>

3 Answers 3

1

In order to have prototypical inheritance work you need to do two things:

  1. Use the new operator when creating the object, in order to have a this with the correct prototype.

    new URLLoad(...)
    
  2. Not return a value from the constructor. The value you are returning doesn't have the correct prototype but has precedence anyway.

    function URLLoad(){
        this.tagId = ...;
        this.timeOut = ...;
    }
    

Of course you might now complain that I am not doing the cacheing. Well, I think it is best to separate the construction from the cacheing.

var cache = {};
function urlLoad(key){
    if(!cache[key]){ cache[key] = new URLLoad(key); }
    return cache[key];
}

If you want to avoid having those exposed cache and URLLoad globals, we can make them private with the module pattern:

var urlLoad = (function(){

    function URLLoad(){...};
    URLLoad.prototype = {...};

    var cache = {};
    function urlLoad(){...};

    return urlLoad;
}()); 
Sign up to request clarification or add additional context in comments.

Comments

0

URLLoad is a constructor. Try prefixing it using the new operator:

new URLLoad("LoadingTxt000003");

3 Comments

URLLoad("LoadingTxt000003"); does run the constructor as I get the alert pop-up.
Constructors are normal functions, but the new operator binds the this variable to a new context. a constructor should always be called using the new operator.
I've prefixed URLLoad("LoadingTxt000003") and URLLoad("LoadingTxt000005") with new and still get the same error.
0

I think your solution is overly complicated. If you want to cache information about your views, just use an object literal and do

var viewCache = {};

Then to add views in, just do

viewCache['LoadingTxt000003'] = 20;

Note that this uses the id of the view element as the key and the timeout as the val, in the cache. Also note that even though [id] looks like an array index, when used on a object literal its just a way to set the key/value pair.

You can expand it by doing something like

viewCache['LoadingTxt000003'] = {'timeout': 20};

Now your cache is an object literal, and its values are object literals as well, which is useful if you are going to store more than one piece of information in your cache.

1 Comment

I'm not trying to cache view info - I've edited my question to hopefully clarify.

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.