Différence réelle entre "propertyIsEnumerable" et " hasOwnProperty" ou tout simp [Résolu]

Signaler
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
-
aerolyte
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
-
Bonjour,
me voici a poser deux questions apres quelques expérimentations dont j'ai joint les résultats.

Quelles sont les différences réelles entre "propertyIsEnumerable" et " hasOwnProperty" ou tout simplement "in"?

package{
import flash.display.MovieClip;

public class Main extends MovieClip{

public function Main(){
var So:MovieClip=new MovieClip();
So.po="salut";
So.x=20;

trace(So.propertyIsEnumerable("po"));//true
trace(So.hasOwnProperty("po"));//true
trace("po" in So);//true

trace(So.propertyIsEnumerable("x"));//false
trace(So.hasOwnProperty("x"));//true
trace("x" in So);//true

trace(So.propertyIsEnumerable("pi"));//false
trace(So.hasOwnProperty("pi"));//false
trace("pi" in So);//false

trace(So.propertyIsEnumerable("y"));//false
trace(So.hasOwnProperty("y"));//true
trace("y" in So);//true
}
}
}


Deuxièmement je voudrais savoir si l'on peut connaitre le nombre de propriété d'un object avec une méthode du genre: S0.prop.length

Sans devoir passer par une boucle sur le string avec une incrémentation: for(var p:String in So){nb++}

Car du coup l'on fait un typage en string ecartant du coup toutes les propriété native,(x, alpha, enabled,...)
J'ai essayer en ne typant pas (p:*), mais cela n'est pas concluant

Par voix de conséquence, dans le test ci dessus, on remarque que pour une propriété native non déclarée sa valeur par défaut, retourne forcement un true
Comment peut-on filtrer les propriétés natives réellement déclarées, même si leur valeur est identique a celle par défaut.

11 réponses

Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
1
bon ben je vais vous faire part de quelques constats pour cloturer ce sujet:

voici mon Main.as
package{
import flash.display.Sprite;

public class Main extends Sprite{
public function Main(){
var Si:DSprite=new DSprite();
Si.p1=true;
Si.p0="yes";
Si.p2=4;
for(var p:String in Si){trace(p);}
}
}
}

mon DSprite.as
package{
import flash.display.Sprite;

dynamic class DSprite extends Sprite{
static var obj:Object;
public function get obj():*{return obj;}
public function set obj(value:*):void{obj=value;}
}
}

Alors j'entend deja Peg me dire "ben c'est juste une custom class".
Oui, mais non, car les recherches n'étaient pas sur le moyens de le faire mais bien sur leurs capicités respectives.

rq: Si dans la doc officiels il est indiqué que les propriétés intégrés ne sont pas enumerable, c'est tout a fait inexacte.
Elles le sont par l'utilisation de la classe flash.utils.describeType;
Celle-ci correspond exactement a ce que je voulais faire c'est a dire à l'élaboration d'une carte des propriétés d'un object au format Xml.

Bien evidement son utilisation pour la plupart des scripteurs, est quasi inutile.
Dans l'exemple ci dessus, j'ai ajouté une couche de propriétés a un objet sprite, Le fait de passer par obj:Obect, me permet de créer les propriétés a la volée, mais en contrepartie seule "l'objet propriété" (obj), ne sera énumerable dans les accesseurs.
C'est a dire que l'on a le choix:

Soit lister en dur, chaque variables dans la classe DSprite, afin de les retrouver individuellement en tant qu'accesseur.

Soit déclarer un objet ,qui s'instancira a chaque declaration de variable, mais du coup il sera le seul acceseur.

OU bien on peut avoir une combinaison des 2.

Certainement le choix se fera en fonction:
>de normes personnelles, professionnelles, ou communautaires...
> de la gestion des valeurs par defaut et de la présence ou nom de la propriétés.

rq2: Si l'on peut setter une valeur par defaut, a ma connaissance il n'existe pas de méthode servent à les getter.
J'entend ceci sous la forme:
IsDefaultValue(So.prop)//boolean

Voici donc mon nouveau domaine de prospection

Je vous remercie
Messages postés
6161
Date d'inscription
dimanche 21 décembre 2003
Statut
Modérateur
Dernière intervention
4 septembre 2013
6
Bonjour, j'ai peur de ne pas avoir bien saisis ta question .. même si je la trouve intéressante pour ces deux méthodes peu utilisées.

Dans la doc de flash il est indiqué clairement :

propertyIsEnumerable
[...]
Indique si la propriété spécifiée existe et est énumérable. Si la valeur est true, la propriété existe et peut être énumérée dans une boucle for..in. La propriété doit exister au niveau de l’objet cible dans la mesure où cette méthode ne vérifie pas la chaîne de prototype de l’objet cible.

Les propriétés que vous créez sont énumérables, contrairement aux propriétés intégrées qui ne le sont généralement pas.

et
hasOwnProperty(name:String):Boolean

Indique si la propriété spécifiée d’un objet est définie. Cette méthode renvoie true si l’objet cible comporte une propriété qui correspond à la chaîne spécifiée par le paramètre name et false dans les autres cas. Les types de propriétés suivants forcent la méthode à renvoyer la valeur true pour les objets qui sont des occurrences de classe, plutôt que des objets de classe :

Propriétés d’occurrence fixes : variables, constantes ou méthodes définies par la classe de l’objet qui ne sont pas statiques.
Propriétés d’occurrence fixes héritées : variables, constantes ou méthodes héritées par la classe de l’objet.
Propriétés dynamiques : propriétés ajoutées à un objet après son instanciation (hors de la définition de classe). Pour ajouter des propriétés dynamiques, la classe de définition de l’objet doit être déclarée avec le mot-clé dynamic.

Les types de propriétés suivants forcent la méthode à renvoyer la valeur false pour les objets qui sont des occurrences de classe :

Propriétés statiques : variables, constantes ou méthodes définies avec le mot-clé statique dans la classe de définition d’un objet ou dans l’une de ses super-classes.
Propriétés de prototype : propriétés définies pour un objet prototype appartenant à la chaîne de prototype de l’objet. Dans ActionScript 3.0, la chaîne de prototype n’est pas utilisée pour l’héritage de classe, mais demeure une autre forme d’héritage valide. Par exemple, une occurrence de la classe Array peut accéder à la méthode valueOf() parce qu’elle est associée à Object.prototype, qui fait partie de la chaîne de prototype de la classe Array. Bien que vous puissiez utiliser valueOf() sur une occurrence d’Array, la valeur renvoyée par hasOwnProperty("valueOf") pour cette occurrence correspond à false.


La différence est nette, et leurs utilisation clairement définies.

Ensuite, si tu veux différencier les propriétés ajoutées d'un objet, il suffit de savoir celles qui sont d'origine dans la class qu'étends ton objet.

C'est à dire que si tu fais :
var toto:MovieClip = new MovieClip()

"toto" aura d'office une propriété x, y, scaleX, scaleY, etc ...

Et si après tu fais :
toto.prop = 25;

Alors "toto" aura une pripriété de plus, mais une qui lui sera propre, et pas à la class MovieClip dont il hérite.

C'est ça le principe des classes custom. Et pour te répondre, le plus efficace serait de faire une méthode statique de ta class Main qui te permettrais de lister les propriétés custom de ta nouvelle classe.

Peg'
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
1
Je reformule mes questions après de nouveaux test

Comment énumérer des propriétés intégrées?

Et Comment les comparer avec leur valeur par défaut ? sans devoir passer par:
for(var p:String in So){
type:String=getQualifiedClassName(So[p])
switch(type){
case int:...
case String:...
...
}
De facon a mettre uniquement en lumière les propriétés actives et laissée de coté celle par défaut

package{
import flash.display.MovieClip;
import flash.utils.getQualifiedClassName;

public class Main extends MovieClip{
public function Main(){
var r0:int;
var So:MovieClip=new MovieClip();
So.po="salut";
So.x=20;

trace(So.propertyIsEnumerable("x"));//false
trace(So.hasOwnProperty("x"));//true
trace("x" in So);//true
trace("///////////////////////////////////////////////////");
trace(So);//20
trace(So);//0
trace(So);//salut
trace(So);//undefined
trace("///////////////////////////////////////////////////");
trace(typeof(So.x));//number
trace(getQualifiedClassName(So.x));//int
trace(typeof(So.po));//string    ??? sans majuscule
trace(getQualifiedClassName(So.po));//String
if(So.y==r0){trace("perdu");}//perdu
}
}
}

Messages postés
6161
Date d'inscription
dimanche 21 décembre 2003
Statut
Modérateur
Dernière intervention
4 septembre 2013
6
en gros, pour savoir si une propriété appartiens à la superclasse (la classe parente), tu peux faire un truc con :
function isOriginalProperty(str:String):Boolean {
return customClass.hasHownProperty(str) && !extendedClass.hasHownProperty(str);
}


Et si ça te renvoie "true", c'est que c'est une propriété custom, sinin que c'est une propriété héritée (ou overridée, si c'est le cas)

Je pense que c'est plus clair ...

Peg'
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
1
Bonjour,
Merci pour ta réponse,

effectivemenr apres mon premier post, j'ai bien vu dans la doc officiel que
" Les propriétés que vous créez sont énumérables, contrairement aux propriétés intégrées qui ne le sont généralement pas."


Je précise que mes tests n'ont pas pour optique de réaliser un fragment de code précis, mais au contraire de définir les possibilité offertes en utilisant les propriétés.
Comme je te l'ai evoqué je brasse du code pour mettre sur pied une écriture plus naturelle.

Du coup, j'aimerais savoir si par principe on peut créer une carte d'identité spécifique a un movieclip en groupant:

-les propriétés étendues qui sont enumerables mais dont on ne peut pas sortir directement le nombre avec mc[*].length

-les propriétés intégrées dont la valeur n'est pas celle par défaut et qui ne sont pas énumerable.
Nétant pas directement enumerable, ou pourrait imaginer tester la valeur de chaque propriété et avec getQualifiedClassName la tester a la valeur par défaut.
Mais c'est très lourd comme démarche.
Cela met en lumière qu'il n'existe pas de méthode native pour comparer une valeur typée a sa valeur par défaut.
trace((mc.x==defaultValue)?"oui":"non");

J'ai regardé succintement, mais sans grand résultat la classe Dictionary

Aussi j'ai vu qu'il était possible de passer la classe Sprite en static, pour permettre les meme manipulation de propriété que la classe MovieClip
a vrai dire j'ai pas bien compris la modifs a faire.
J'ai dans l'optique de normaliser des couches d'informations sur la plupart des autres médias.

Pour illustrer
monSon.auteur="xxxxx";
monImage.auteur="yyyyy";
monText.auteur="zzzzzzz";

Le plus naturellement du monde on pourra stocker et traiter l'information sans ce soucier du type d'objet.

Oui,les applications sont illimitées...

Cordialement
Messages postés
6161
Date d'inscription
dimanche 21 décembre 2003
Statut
Modérateur
Dernière intervention
4 septembre 2013
6
En gros, tu cherches à faire une class custom .. rien de plus ?

Peg'
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
1
Pas uniquement, la démarche est globale.

L'idée de départ est de pouvoir associer a chaque objet "médium" (displayobject + sound + futurs objets interactifs(odorat, toucher)une carte de propiétés (intégrées + étendues) spécifique a cet objet et pouvant etre traité de facon globale sans ce soucier du typage.

Du fait de l'acquisition dynamique de la plupart de ces propriétés, je cherche a déterminé quel sont les possibiltés actuelles pour les lister, les énumérées, et les normaliser.

D'ou quelques tests qui m'amêne a poser ces questions.

1]Comment enumérer des propriétés intégrer? Sinon par quel biais ce serais possible sans devoir les tester une a une ?

2]Comment lister les prpriétés étendus sans passer par for(var p:String in So){nb++}?

3]Comment comparer une valeur a celle par défaut du type, sans passer par un switch sur getQualifiedClassName?

4]comment déclarer des prpriétés étendu sur d'autre classe? car j'ai pas bien compris le principe?

Voila les questions devraient etre plus claires
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
1
function isOriginalProperty(str:String):Boolean {
return customClass.hasHownProperty(str) && !extendedClass.hasHownProperty(str);
}


Pour l'exemple il serait plus pertinent de faire

function isOriginalProperty(str:String):Boolean {
return customClass.hasHownProperty(str) && customClass.propertyIsEnumerable(str);
}


Quoi qu'il en soit la détermination de l'origine des propriétés ne me pose pas vraimment de pb
Messages postés
6161
Date d'inscription
dimanche 21 décembre 2003
Statut
Modérateur
Dernière intervention
4 septembre 2013
6
Tu cherches à compliquer quelque chose de simple, sous prétexte de simplification ... j'ai un doute sur l'interêt de la démarche.

Peg'
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
1
en espérant avoir un debut de réponse sur les 3premières questions, je souhaiterais savoir quelles est la meilleurs facon des 3 suivante.

package{
import flash.display.Sprite;

public class DSprite extends Sprite{
private var _p0:*;
private var _p1:*;

public function get p0():*{return _p0;}
public function set p0(value:*):void{_p0=value;}

public function get p1():*{return _p1;}
public function set p1(value:*):void{_p1=value;}
}
}

package{
import flash.display.Sprite;

public class DSprite1 extends Sprite{
public var p0:*;
public var p1:*;
}
}
package{
import flash.display.Sprite;

dynamic class DSprite2 extends Sprite{
static var p0:*;
static var p1:*;
}
}

Comme je me retrouve a devoir déclarer chaque variable dans la classe étendues, je vais essayer de voir si i est pas possible de les attribuer dynamiquement comme les movieclips.
Messages postés
465
Date d'inscription
mardi 17 avril 2007
Statut
Membre
Dernière intervention
4 mai 2013
1
Je viens de découvrir la class: flash.utils.describeType;

package{
import flash.utils.describeType;

public class Main extends MovieClip{
public function Main(){
var Si:DSprite=new DSprite();
Si.p0="yes";
Si.p1=true;

var description:XML = describeType(Si);
trace(description..accessor.@name.toXMLString());
}
}
}


du coup j'ai ma réponse; la premiere est la plus transparente à la compilation