On Thu, 22 Mar 2012 00:15:40 -0700, Dmitriy Sintsov questpc@rambler.ru wrote:
- Krinkle krinklemail@gmail.com [Wed, 21 Mar 2012 18:51:45 +0100]:
Few points:
- The easiest way to understand it is to consider "sparse arrays" to
not
exist in javascript. It doesn't throw an exception if you try it, but it's not supposed
to
be posisble, so don't.
In Chrome, executing the following code: var a = []; a[0] = 'a'; a[2] = 'c'; worked, however debugger inspector shows 'undefined' elements between real elements of array. And the length is counted for 0..last element, including the undefs. However, for..in worked for such arrays fine, but may be inefficient - I do not think it has hashes or linked lists to skip the undefs, it probably just skips them one by one. That worked in IE8/IE9/FF/Chrome so I must not be first coder who used that.
That's the very definition of an array. An array is a list, the keys are indexes. By definition you cannot have an index that does not exist. If an item in the array does not exist then the items after it take on earlier indexes and the length is shorter. If you have a case where 0 and 2 exists but 1 is not supposed to exist then you're not using an array, you're using a hashtable, map, etc... For that purpose you should be using Object like a hashtable: var h = {} h[0] = 'a'; h[2] = 'c';
You can use for..in on such a thing. And you also shouldn't have to worry about using hasOwnProperty on it. If anyone is stupid enough to set something on Object.prototype a lot more than your script will break.
I switches to {} and $.each() two days ago, so that's already the past.
- Sparse objects don't exist in any language afaik. What you created
is
just a regular plain object.
I was mentioning JS objects with numeric keys - I didn't know they are silently converted to numbers. Now I removed parseInt() from my code.
- As I said before I think there is no point in using $.each() in this case. It is nice if you need a context but as you already found out,
more often than not it's actually a burden to have to deal with it if you just want a loop inside an existing context. I would've kept the for-in loop you originally had which was just fine, only change the array into an object.
Maybe I'll switch to for ...in back then however I scared by "basic" prototypes so maybe I'll check .hasOwnProperty() then, too. Still haven't decided that.
I'd have to look further into the actual code to know what you mean here, but there isn't really such thing as "refactorign a JS class into a ResourceLoader module". For one, javascript doesn't have classes, but that's just word choise. Secondly, ResourceLoader "just" loads
Actually, creating JS function and assigning the prototypes to it and then instantiating it via new operator and then adding properties to it's context, including some from it's own prototypes works like classes. Prototypes are really similar to virtual methods tables available in another OO languages, but another languages manipulate them indirectly, in higher and better level than JS. Frankly, I am not much a fan of JS, however I have no another widespread choice for client-programming web.
You don't have to refactor anything. There are a few things that it enforces (such as execution of the javascript file in a local
context),
but other than that you don't have to change anything "for
ResourceLoader".
There are a lot of conventions and best practices often associated
with
"porting to ResourceLoader" but that's more along the lines of "now
that
we're working on this, lets get rid of crappy code and make it nice", not anything ResourceLoader actually requires.
I'm curious what kind of problems you are referring to here? The kind
of
problems you didn't have when you loaded jQuery in MediaWiki 1.15
The problems are simple - when I load another module with mw.loader.using, then call it's module from mw.loader.using callback, there is no return to original module. So I am enforced to build inflexible chain of calling main module directly from loaded module main context. I got used to it, although that was a little disappointment.
Now I have another pain: mw.msg() caches messages quite aggressively, even though I put the following lines in LocalSettings.php: $wgResourceLoaderDebug = true; $wgEnableParserCache = false; $wgCachePages = false;
I got the same old version of message, even after multiple Ctrl+R in Chrome, action=purge and even httpd restats. How can I make mw.msg() being updated every time I change i18n file of my extension? Maybe the evil provider caches some requests though :-( I probably should check with Wireshark. It's tiresome that fighting with environment takes too much of the time. Dmitriy