Javascript: retrieve objects by id, using an object, not an array
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>
In order to have prototypical inheritance work you need to do two things:
Use the new operator when creating the object, in order to have a
this
with the correct prototype.new URLLoad(...)
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;
}());
URLLoad
is a constructor. Try prefixing it using the new operator:
new URLLoad("LoadingTxt000003");
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.
精彩评论