Posts

Showing posts with the label Array

Array extras and Objects

When Array extras landed in JavaScript 1.6 I had, probably together with other developers, one of those HOORRAYYY moment ... What many libraries and frameworks out there still implement, is this sort of universal each method that supposes to be compatible with both Arrays and Objects. A Bit Messed Up What I have never liked that much about these each methods is that we have to know in advance in any case if the object we are passing is an Array, an ArrayLike one, or an Object. In latter case, the callback passed as second argument will receive as second argument the key , and not the index , which simply means we cannot trust a generic callback unless this does not check per each iterated item the second argument type, or unless we don't care at all about the second argument. In any case I always found this a bad design. If we think about events, as example, it's totally natural to expect a single argument as event object and then we can act accordingly. This let us reuse c...

Array.prototype.slice VS Arrayfication

One of the most common operations performed on daily basis directly or indirectly via frameworks and libraries is Array.prototype.slice calls over non Array elements such HTMLCollection , NodeList , and Arguments . Why We Perform Such Operation The Function.prototype.apply works only with object created through the [[Class]] Array or Arguments. In latter case we may like to avoid ES3 arguments and named arguments mess when dealing with indexes. Finally, in most of the case we would like to perform Array operations over ArrayLike objects to filer, map, splice, change, modify, etc etc ... The Slice Cost Let's perform over an ArrayLike object of length 2000, 2000 slice calls (change the length if you have such powerful machine): // create the ArrayLike object for(var arguments = {length:2000}, i = 0; i arguments[i] = i; ; // define the bench function function testSlice(arguments) { var t = new Date; for (var slice = Array.prototype.slice, i = 0, length = arguments.lengt...

[COW] A Generic ArrayObject Converter

Few days ago I wrote about a fast Array slice implementation for every browser, a callback able to convert " every collection " into an Array. For collection, I mean every instance with a length attribute and an index access Array like. This object, for example, could be considered as a collection: var generic = { length: 2, "0": "abc", "1": "def" }; Above instance is a basic model of most common libraries such jQuery, prototype, base, and every other based over an Array like prototype. Some library could coexist in the same page without problems but not every library implement a method to create a copy of another collection into a new instance of the library itself. As example, a jQuery or Sizzle result into another instance, a generic DOM collection into a jQuery object, etc etc. All these instances could be passed via Array.prototype.push to be populated, and thanks to this peculiarity we can obtain every kind of instance f...

A fast Array slice for every browser

It is an extremely common task and one of the most used prototype in libraries and applications: Array.prototype.slice The peculiarity of this prototype is to create an Array from an Array like Object such arguments, HTMLCollection, other kind of lists as jQuery results. Every browser, except Internet Explorer, allows direct calls via native prototype obtaining, obviously, best performances. In IE, we have different ways to make this task possible, and these ways are mainly classic loops, or the isArray check to know when it is possible to perform the native call or not. isArray = (function(toString){ return function(obj){ return toString.call(obj) === "[object Array]"; }; })(Object.prototype.toString); Even using a closure, above function could slow down performances, specially in those libraries where Array conversions are performed almost everywhere. As we all know, Internet Explorer behaves weird "sometimes", and one of the weirdest things is tha...

A fast and crossbrowser function to make an Array

An absolutely common task present in almost every library, is to transform a generic collection/list of objects or DOM Elements into a friendly Array. Cases Scenario It is possible to apply directly an Array.prototype.slice call to quickly return an Array It is not possible at all apply every kind of Array prototype to the list Cases scenario detection When we execute a piece of JavaScript in a web page, we can assume that we have at least one DOM element in that page, as the script itself for example, so it is always possible to obtain a collection of elements calling document.getElementsByTagName("script") or a generic ("*") in this case probably superflous considering the latter assumption. Cross browser and fast makeArray proposal var makeArray = function(push, slice){ try{ // Andrea Giammarchi proposal slice.call(document.getElementsByTagName("script"), 0); return function(array, results){ array = array instan...

Habemus Array ... unlocked length in IE8, subclassed Array for every browser

History I do not know how many time, during these years, JavaScript Ninjas tried to subclass the native Array to create libraries over its powerful methods without losing performances. I have finally discovered the way to remove locked length from Internet Explorer 8 , and to solve problems with every other browser. We tried to inherit Array instead of Object This is where my last trip started, simply looking at arguments behaviour. It was there, since 2000 when I started to code in JavaScript, and it was so simple that probably few developers thought about them! var o = { length:0, push:Array.prototype.push, toString:Array.prototype.join }; o.push(1,2,3); alert(o); // 1,2,3 arguments, in JavaScript, is an instanceof Object, and not an Array, as is in ActionScript since version 1.0 What we have done all this time, is to use Array.prototype methods injecting a basic object, with a simple length parameter, inside. If an object with a length value can be used as an Arra...

JavaScript ArrayObject

I think this constructor could be a good start point for a lot of projects. We know that IE has problems while it try to extend an array, disabling length modification. That's why I have created this wrapper that does not require weird strategies (e.g. iframe with a different enviroment) and works with a wide range of browsers. Honestly, I did not test performances against pure arrays, but I did everything to make code as fast as possible, using good practices and creating an in-scope shortcut for the Array.prototype. Have a look here if you are interested in this constructor, ignore them if you do not think this is a good idea :) P.S. Please note that this constructor does not care about missed prototypes, it only does its wrapping work and nothing else. To improve Array compatibility and methods, please remember my JSL Revision . Including them in your page, You'll not have problems with every ArrayObject method, eccept for reduce and reduceRight (I will create a good implem...