Voir le flux RSS

danielhagnoul

Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet

Noter ce billet
par , 23/11/2014 à 00h33 (710 Affichages)
Dans le billet précédent, nous avons vu comment recueillir la valeur de la propriété [[Class]] avec la fonction getType().

Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
function getType( Obj ){
    return Object.prototype.toString.call( Obj ).match( /\s([a-zA-Z]+)/ )[ 1 ].toLowerCase();
}

Pour vérifier le typage des propriétés d'un objet on peut utiliser un objet englobant (proxy), mais l'API Proxy sera au mieux disponible en ES6. De plus, la technique du proxy à la réputation d'être difficile à mettre au point pour couvrir tous les cas d'utilisation et de modification d'un objet, certains auteurs signalent aussi des pertes de mémoire.

Nous allons utiliser une technique moins exaltante, mais plus sûre et utilisable en ES5.

La fonction setModel

Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function setModel( Obj ){
 
    if ( getType( Obj ) === "object" ){
 
        Obj[ "_objectModel" ] = Object.create( Object.prototype );
 
        Object.getOwnPropertyNames( Obj ).forEach( function( key ){
 
            if ( key != "_objectModel" ) {
 
                Object.defineProperty( Obj[ "_objectModel" ], key, {
                    "value" : getType( Obj[ key ] ),
                    "enumerable" : true
                });
            }
        });
    } else {
        throw "Erreur dans setModel(), " + Obj + " n'est pas un objet";
    }
}

Cette fonction ajoute simplement une propriété "_objectModel" à un objet "source". La valeur de cette propriété est un objet qui contient le type des propriétés de l'objet "source".

La méthode doit être appelée directement après la construction d'un objet et elle peut être appelée après chaque ajout de propriétés.

Les exemples d'utilisation vous aideront à y voir plus clair.

Exemple simpliste

Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
var Personne = {};
Personne.nom = "Daniel";
setModel( Personne );
console.log( Personne );
 
/*
 * nom: "Daniel"
 * _objectModel:
 *  nom: "string"
 */

Exemple d'un objet JSON

Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
 * Définition de l'objet Animal.
 * 
 * On peut utiliser this._objectModel dans
 * le mutateur (set) mais n'oublier d'appeler
 * setModel( Animal ) sous peine d'erreur
 * lors de l'utilisation de l'objet.
 */ 
var Animal = Object.create( Object.prototype, {
    "_nomAnimal": {
        "value" : "",
        "writable" : true,
        "configurable" : true
    },
    "nomAnimal" : {
        "get" : function(){
            return this._nomAnimal;
        }, 
        "set" : function( value ){
            if ( this._objectModel._nomAnimal === getType( value ) ) {
                this._nomAnimal = value;
            }
        },
        "enumerable" : true,
        "configurable" : true
    }
});
 
setModel( Animal );
 
Animal.nomAnimal = "Makita";
 
console.log( Animal );
 
/*
 * _nomAnimal: "Makita"
 * nomAnimal: (...) get set
 * _objectModel:
 *   _nomAnimal: "string
 *   "nomAnimal: "string"
*/

Exemple d'héritage avec ajout d'un accesseur (get) et d'un mutateur (set)

Code JavaScript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * Construction des fonctions
 */ 
var Animal = function( name ){
        this._name = name;
    },
    Dog = function( name, pays ){
        Animal.call( this, name );
        this._pays = pays;
    };
 
/*
 * Construction du prototype d'Animal
 */ 
Animal.prototype = {
    "sayName" : function() {
        return this._name;
    }
};
 
/*
 * Héritage
 */ 
Dog.prototype = Object.create( Animal.prototype );
 
/*
 * Ajout de propriétés
 */ 
Dog.prototype.sayName = function( str ){
    var texte = str || "";
    return ( texte + Animal.prototype.sayName.call( this ) );
};
 
Dog.prototype.bark = function(){
    return "Woof!";
};
 
/*
 * Construction des objets
 */
var MonChien = new Dog( "Youki", "Belgique" ),
    AutreChien = new Dog( "Caline", "France" );
 
/*
 * Ajout du modèle de type
 */
setModel( MonChien );
setModel( AutreChien );
 
/*
 * Ajout de la propriété "vacciner"
 */ 
Object.defineProperties( AutreChien, {
    "vacciner" : {
        "value" : true,
        "enumerable" : true
    }
});
 
/*
 * Reconstruction du modèle de type
 * 
 * Inutile, vu l'ajout suivant, mais
 * montre que la multiplicité des appels
 * est possible.
 */
setModel( AutreChien );
 
/*
 * Ajout d'un accesseur et d'un mutateur
 */ 
Object.defineProperty( AutreChien, "name", {
    "get" : function( ){
        return this._name;
    },
    "set" : function( value ) {
        if ( this._objectModel._name === getType( value ) ) {
            this._name = value;
        }
    },
    "enumerable" : true,
    "configurable" : true
});
 
/*
 * Reconstruction du modèle de type
 */
setModel( AutreChien );
 
/*
 * Utilisation du mutateur
 */ 
AutreChien.name = "Elliot";
 
console.log( AutreChien );
 
/*
 *  _name: "Elliot"
 *  _pays: "France"
 *  vacciner: true
 *  name: (...) get set
 *  _objectModel: {
 *    _name: "string"
 *    name: "string"
 *    _pays: "string"
 *    vacciner: "boolean"
*/

Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog Viadeo Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog Twitter Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog Google Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog Facebook Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog Digg Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog Delicious Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog MySpace Envoyer le billet « Construction d'un modèle de type dans le but d'améliorer la gestion des propriétés d'un objet » dans le blog Yahoo

Mis à jour 07/06/2015 à 11h57 par danielhagnoul

Catégories
Javascript , Développement Web

Commentaires