Problème avec Array.prototype

Résolu
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 - 15 août 2007 à 00:24
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 - 15 août 2007 à 16:56
Bonjour à tous,

La syntaxe Array.prototype me pose un problème !

En l'occurence c'est avec le JSONstringifier (http://json.org/js.html) qui comporte cette fonction :
Array.prototype.toJSONString = function () { ... }

Le résultat c'est que tous mes tableaux ont une case en plus, dont le contenu est "toJSONString" !

J'avais eu exactement le même problème en utilisant cette excellent classe où il y avait

function inArray(text)
{
    for (a=0;a<this.length;a++)
    {
        if(this[a] == text)
        {
            return true;
        }
    }
}
Array.prototype.inArray = inArray;

et ça rajoutait une case avec "inArray" à tous mes tableaux.
Arto_8000 disait de rajouter une condition dans les boucles for(i in array) pour zapper la case en question, mais ce n'est pas envisageable comme solution.

Comment faire pour éviter ce problème ? Merci !

4 réponses

the_wwt Messages postés 177 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 16 janvier 2009 1
15 août 2007 à 16:29
Re,
et bien tu n'as pas le choix, c'est le seul moyen....
Tien voilà ce qu'en dis l'auteur de la librairie prototypejs:
Many JavaScript authors have been misled into using the
for
in
JavaScript construct to loop over array elements. This kind of code just won’t work with Prototype.

You see, the ECMA 262 standard, which defines ECMAScript 3rd edition, supposedly implemented by all major browsers including MSIE, defines numerous methods on
Array
(§15.4.4), including such nice methods as
concat
,
join
,
pop
and
push
, to name but a few among the ten methods specified.

This same standard explicitely defines that the
for
in
construct (§12.6.4) exists to enumerate the properties of the object appearing on the right side of the
in
keyword. Only properties specifically marked as non-enumerable are ignored by such a loop. By default, the prototype and the
length
properties are so marked, which prevents you from enumerating over array methods when using
for
in
. This comfort led developers to use
for
in
as a shortcut for indexing loops, when it is not its actual purpose.

However, Prototype has no way to mark the methods it adds to
Array.prototype
as non-enumerable. Therefore, using
for
in
on arrays when using Prototype will enumerate all extended methods as well, such as those coming from the
Enumerable
module, and those Prototype puts in the
Array
namespace (described in this section, and listed further below).

What is a developer to do?
You can revert to vanilla loops:

for(var index = 0; index < myArray.length; ++index) {
var item = myArray[index];
// Your code working on item here...
}


Or you can use iterators , such as
each
:

myArray.each(function(item) {
// Your code working on item here...
});


This side-effect enforcement of the true purpose of
for
in

is actually not so much of a burden: as you’ll see, most of what you
used to loop over arrays for can be concisely done using the new
methods provided by
Array
or the mixed-in
Enumerable
module. So manual loops should be fairly rare.

A note on performance
Should you have a very large array, using iterators with lexical closures (anonymous functions that you pass to the iterators, that get invoked at every loop iteration), such as
each
, or relying on repetitive array construction (such as
uniq
),
may yield unsatisfactory performance. In such cases, you’re better off
writing manual indexing loops, but take care then to cache the
length
property and use the prefix
++
operator:

// Custom loop with cached length property: maximum full-loop performance on very large arrays!for(var index 0, len myArray.length; index < len; ++index) {
var item = myArray[index];
// Your code working on item here...
}
3
the_wwt Messages postés 177 Date d'inscription jeudi 5 octobre 2006 Statut Membre Dernière intervention 16 janvier 2009 1
15 août 2007 à 12:19
Bonjour,
ce n'est pas un problème, c'est la nature même du javascript où tout est tableau.
Ainsi un objet est un tablau...
Pour parcourir un tableau la bonne syntaxe est:for(var i 0, length array.length; i < length; i++){
....
}

Cdlt,
Pierrick
0
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
15 août 2007 à 14:13
Bonjour ! et merci de ta réponse.

Mais j'ai des tableaux associatifs, je suis obligé de les parcourir avec for (i in array) ...

Il doit bien y avoir un moyen de rajouter une méthode à l'objet Array sans rajouter une case à tous les tableaux, non ?

Je ne comprends pas pourquoi il y a ce comportement. En quoi le fait que tout soit un tableau explique que prototype rajoute une case ?

Merci !
0
Evangun Messages postés 1980 Date d'inscription dimanche 20 février 2005 Statut Membre Dernière intervention 24 septembre 2012 4
15 août 2007 à 16:56
L'explication est absolument parfaite, merci infiniment de m'avoir montré ça !
0
Rejoignez-nous