IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Améliorons la robustesse et la sécurité de nos objets

Adapter jQuery à vos besoins, niveau 3

Publié le 25 mars 2012 et mis à jour le 25 mars 2012


II. Le système objet d'ES5
II-A. Les méthodes Object
II-B. Construction d'objet et héritage différentiel
II-C. Ajout de méthodes au méta-objet Object
II-D. Tests des méthodes ajoutées au méta-objet Object


II. Le système objet d'ES5


II-A. Les méthodes Object

warning Ceci n'est pas un tutoriel sur le système objet d'ES5, mais un simple rappel de ce qu'il ne faut pas avoir oublier pour être capable de s'en servir.
Methode Description
Object.create( prototype [, PropertiesObject ]) Retourne un nouvel objet ou un objet dérivé.
Object.defineProperty( Obj, key, PropertyObject ) Ajoute une propriété à un objet existant.
Object.defineProperties( Obj, PropertiesObject ) Ajoute des propriétés à un objet existant.
Object.keys( Obj ) Retourne un array contenant les clés énumérables d'un objet.
Object.getOwnPropertyNames( Obj ) Retourne un array contenant les clés énumérables et non énumérables d'un objet
Object.getOwnPropertyDescriptor( Obj, key ) Retourne la propriété correspondant à une clé d'un objet.
Object.preventExtensions( Obj ) Empêche toute extension d'un objet.
Object.seal( Obj ) Empêche toute suppression des propriétés d'un objet.
Object.freeze( Obj ) Gèle un objet : aucune suppression ou modification des propriétés n'est autorisée.
Object.isExtensible( Obj ) Retourne true si l'objet est extensible.
Object.isSealed( Obj ) Retourne true si l'objet est scellé.
Object.isFrozen( Obj ) Retourne true si l'objet est gelé.
Object.getPrototypeOf( Obj ) Retourne le prototype de l'objet.

Création d'un nouvel objet : var ObjParent = Object.create( {}, propertiesObject );

Création d'une propriété : "key" : { value : [string || number || array || object || function] [, Descripteurs ] }

Création d'un acceseur (get) et d'un mutateur (set) : "key" : { [ get : function(){ ... } ] [, set : function( value ) { ... } ] [, Descripteurs ] }

S'il n'y a pas d'acceseur key n'est pas consultable, s'il n'y a pas de mutateur key n'est pas modifiable. S'il y a un accesseur ou un mutateur value et le descripteur writable sont undefined par défaut et ils ne peuvent pas être modifiés.

Les descripteurs sont des booléens ayant la valeur false par défaut :
  1. writable : doit être true pour pouvoir modifier value ;
  2. enumerable : doit être true pour que la propriété soit énumérable ;
  3. configurable : doit être true pour pouvoir modifier la propriété
Nous préfixerons :
  • Les propriétés non énumérables avec un tiret bas pour les distinguer de l'accesseur (get) et du mutateur (set) homonymes ;
  • Les objets incomplets, inutilisables en l'état, avec le préfixe "i" ;
  • Les objets gelés (freeze : suppression ou modification interdite) avec la lettre "g" ;
  • Les objets scellés (seal: suppression interdite) avec la lettre "s" ;
  • Les objets dont l'extension est interdite (preventExtensions : extension interdite) avec la lettre "e" ;
  • Les objets modifiables uniquement (e + s) avec les lettres "es" ;
  • Les objets immuables (e + g) avec les lettres "eg".

II-B. Construction d'objet et héritage différentiel

Construction d'un nouvel objet : var ObjParent = Object.create( { /* contenu du prototype, tous les descripteurs sont true par défaut */ }, { /* Propriétés, tous les descripteurs sont false par défaut */ } ); ou var ObjParent = Object.create( {}, PropertiesObj );

On peut également construire un objet en utilisant le prototype d'un autre objet : var Obj2 = Object.create( Object.getPrototypeOf( Obj1 ), PropertiesObj );

Héritage : var ObjEnfant = Object.create( ObjParent ); ou var ObjEnfant = Object.create( ObjParent, PropertieObj );.


II-C. Ajout de méthodes au méta-objet Object

Pour construire une hiérarchie d'objets, nous utiliserons exclusivement le clonage et l'extension d'objet, nous avons donc besoin d'une méthode de clonage et d'extension d'objet compatible avec les objets ES5.

warning L'extension d'objet est une technique destructive. Si deux objets possèdent la même clé (key), c'est la propriété de l'objet qui étend qui remplace celle de l'objet étendu. L'ordre des objets passé en paramètre d'une méthode d'extension détermine le contenu du nouvel objet. Cette technique est très courante en jQuery, mais $.extend() est incompatible avec les objets ES5 car il copie uniquement les propriétés énumérables et tous les descripteurs sont explicitement passés à true. Ce comportement est dû au fait qu'il fait une simple copie : target[ key ] = source[ key ].
Nous préfixerons les nouvelles méthodes avec dvjh pour éviter toute collision avec les prochaines évolutions de la norme ECMAScript (ES6 est déjà sur la ligne de départ).
Ajout de nouvelles méthodes :
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.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
"use strict"; 
 
 /* 
 * var ObjFinal = Object.dvjhClone( Obj ); 
 * Retourne ObjFinal ou null en cas d'échec. 
 * 
 * Crée un nouvel objet à partir du prototype d'Obj, 
 * puis lui ajoute les propriétés d'Obj. 
 * 
 * Object.dvjhCloneAndProperties( Obj, PropertiesObj ); 
 * 
 * Crée un nouvel objet à partir du prototype d'Obj, 
 * puis lui ajoute les propriétés d'Obj, puis lui 
 * ajoute les propriétés contenues dans PropertiesObj. 
 * 
 * var ObjFinal = Object.dvjhExtend( Obj1, Obj2 [, ... , ObjN] ); 
 * Retourne ObjFinal ou null en cas d'échec. 
 * L'ordre des objets ObjX détermine le contenu de l'objet ObjFinal. 
 * 
 * Crée un dvjhClone d'Obj1 et lui ajoute les propriétés  
 * des objets suivants. 
 * 
 * Les causes d'échec peuvent être multiples. 
 * 
 * L'erreur la plus fréquente résulte du fait que deux  
 * objets possèdent une clé identique et que la propriété  
 * correspondant à cette clé est non configurable dans  
 * l'objet étendu. 
 * 
 * Pour deux clés identiques, la première étant configurable, 
 * c'est le contenu de la propriété d'ObjX+1 qui remplace celle 
 * de ObjX. 
 * 
 * Object.dvjhExtendAndProperties( Obj1, ..., ObjN, PropertiesObj ); 
  * 
 * Crée un dvjhClone d'Obj1 et lui ajoute les propriétés  
 * des objets suivants, puis lui ajoute les propriétés contenues  
 * dans PropertiesObj. 
*/ 
Object.defineProperties( Object, { 
    'dvjhClone': { 
        value : function( Obj ) { // Object.dvjhClone( Obj );	 
			var	NouvelObjet = null; 
			 
			if ( typeof Obj === "object" ){ 
				try { 
					NouvelObjet = Object.create( Object.getPrototypeOf( Obj ) ); 
					 
					Object.getOwnPropertyNames( Obj ).forEach( function( key ){ 
						Object.defineProperty( NouvelObjet, key,  
								Object.getOwnPropertyDescriptor( Obj, key ) ); 
					}); 
				} 
				catch( evt ){ 
					return null; 
				} 
			} 
			 
			return NouvelObjet; 
        }, 
		enumerable : true 
    }, 
    'dvjhCloneAndProperties': { 
        value : function( Obj, Props ) { 
			var NouvelObjet = Object.dvjhClone( Obj ); 
			 
			if ( NouvelObjet && typeof Props === "object" ){ 
				try { 
					Object.defineProperties( NouvelObjet, Props ); 
				} 
				catch( evt ){ 
					return null; 
				} 
			} 
			 
			return NouvelObjet; 
        }, 
		enumerable : true 
    }, 
    'dvjhExtend': { 
        value : function(){ 
			var args = Array.prototype.slice.call( arguments ), 
				Obj1 = args.shift(), 
				Obj2 = null, 
				NouvelObjet = null; 
				 
			if ( args.length > 0 && typeof Obj1 === "object" ){ 
				NouvelObjet = Object.dvjhClone( Obj1 ); 
			} else { 
				return null; 
			} 
			 
			while( args.length > 0 ){ 
				Obj2 = args.shift(); 
				 
				if ( typeof Obj2 === "object" ){ 
					try { 
						Object.getOwnPropertyNames( Obj2 ).forEach( function( key ){ 
							Object.defineProperty( NouvelObjet, key,  
									Object.getOwnPropertyDescriptor( Obj2, key ) ); 
						}); 
					} 
					catch( evt ){ 
						return null; 
					} 
				} 
			} 
			 
			return NouvelObjet; 
        }, 
        enumerable : true 
    }, 
	"dvjhExtendAndProperties" : { 
		value : function(){ 
			var args = Array.prototype.slice.call( arguments ), 
				Props = args.pop(), 
				Obj1 = args.shift(), 
				Obj2 = null, 
				NouvelObjet = null; 
				 
			if ( args.length > 0 && typeof Obj1 === "object" ){ 
				NouvelObjet = Object.dvjhClone( Obj1 ); 
			} else { 
				return null; 
			} 
			 
			while( args.length > 0 ){ 
				Obj2 = args.shift(); 
				 
				if ( typeof Obj2 === "object" ){ 
					try { 
						Object.getOwnPropertyNames( Obj2 ).forEach( function( key ){ 
							Object.defineProperty( NouvelObjet, key,  
									Object.getOwnPropertyDescriptor( Obj2, key ) ); 
						}); 
					} 
					catch( evt ){ 
						return null; 
					} 
				} 
			} 
			 
			if ( NouvelObjet && typeof Props === "object" ){ 
				try { 
					Object.defineProperties( NouvelObjet, Props ); 
				} 
				catch( evt ){ 
					return null; 
				} 
			} 
			 
			return NouvelObjet; 
		}, 
		enumerable : true 
	} 
}); 

II-D. Tests des méthodes ajoutées au méta-objet Object

Liste des tests
  1. Création d'un nouvel objet (iPersonne ) par clonage d'un objet classique (Henri) et ajout de nouvelles propriétés. Création de deux clones (Pierre et Daniel) et tests des méthodes.
  2. Création d'un nouvel objet ES5 (Moi) par extension d'un clone de l'objet ES5 Daniel avec l'objet ES5 Pays.
  3. Construction et test d'une hiérarchie d'objets ES5.
Test n° 1 :
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.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
"use strict"; 
 
function Hello( name ){ 
	this.name = name; 
} 
 
Hello.prototype = { 
	"says" : function(){ 
		return "je m'appelle " + this.name; 
	} 
}; 
 
var ObjHenri = new Hello( "Henri" ); 
 
var iPersonne = Object.dvjhCloneAndProperties( ObjHenri, { 
	"_prenom" : { 
		value : "", 
		writable : true 
	}, 
	"_nom" : { 
		value : "", 
		writable : true 
	}, 
	"_adresse" : { 
		value : "Belgique", 
		writable : true 
	}, 
	"_numero" : { 
		value : 0, 
		writable : true 
	}, 
	"prenom" : { 
		get : function(){ 
			return this._prenom; 
		}, 
		set : function( value ){ 
			if ( typeof value === "string" && value.length > 1 ){ 
				this._prenom = value; 
			} else { 
				throw Error( "La valeur (" + value + ") n'est pas un texte" ); 
			} 
		}, 
		enumerable : true 
	}, 
	"nom" : { 
		get : function(){ 
			return this._nom; 
		}, 
		set : function( value ){ 
			if ( typeof value === "string" && value.length > 1 ){ 
				this._nom = value; 
			} else { 
				throw Error( "La valeur (" + value + ") n'est pas un texte" ); 
			} 
		}, 
		enumerable : true 
	}, 
	"adresse" : { 
		get : function(){ 
			return "J'habite en " + this._adresse; 
		}, 
		set : function( value ){ 
			if ( typeof value === "string" && value.length > 1 ){ 
				this._adresse = value; 
			} else { 
				throw Error( "La valeur (" + value + ") n'est pas un texte" ); 
			} 
		}, 
		enumerable : true 
	}, 
	"numero" : { 
		get : function(){ 
			return this._numero; 
		}, 
		set : function( value ){ 
			if ( typeof value === "number" ){ 
				var n = parseInt( value, 10 ); 
				 
				if ( isNaN(n) || n < 100){ 
					throw Error( "La valeur (" + value +  
						") n'est pas un entier supérieur ou égal à 100" ); 
				} else { 
					this._numero = n; 
				} 
			} else { 
				throw Error( "La valeur (" + value + ") n'est pas un nombre" ); 
			} 
		}, 
		enumerable : true 
	}, 
	"init" : { 
		value : function( prenom, nom, numero, adresse ){ 
			if ( prenom ) this.prenom = prenom; 
			if ( nom ) this.nom = nom; 
			if ( numero )this.numero = numero; 
			if ( adresse ) this.adresse = adresse; 
		}, 
		enumerable : true 
	} 
}); 
 
try { 
	console.log( iPersonne, Object.keys( iPersonne ) ); 
	 
	Object.getOwnPropertyNames( iPersonne ).forEach( function( key ){ 
		var props = Object.getOwnPropertyDescriptor( iPersonne, key ); 
		 
		console.log( "iPersonne : key = ", key, ", value = ", props.value,  
						", writable = ", props.writable,  
						", enumerable = ", props.enumerable,  
						", configurable = ", props.configurable ); 
	}); 
	 
/* 
Résultat dans Firebug : 
Object { name="Henri", adresse="J'habite en Belgique", numero=0} ["name", "prenom", "nom", "adresse", "numero", "init"] 
iPersonne : key = name , value = Henri , writable = true , enumerable = true , configurable = true 
iPersonne : key = _prenom , value = , writable = true , enumerable = false , configurable = false 
iPersonne : key = _nom , value = , writable = true , enumerable = false , configurable = false 
iPersonne : key = _adresse , value = Belgique , writable = true , enumerable = false , configurable = false 
iPersonne : key = _numero , value = 0 , writable = true , enumerable = false , configurable = false 
iPersonne : key = prenom , value = undefined , writable = undefined , enumerable = true , configurable = false 
iPersonne : key = nom , value = undefined , writable = undefined , enumerable = true , configurable = false 
iPersonne : key = adresse , value = undefined , writable = undefined , enumerable = true , configurable = false 
iPersonne : key = numero , value = undefined , writable = undefined , enumerable = true , configurable = false 
iPersonne : key = init , value = function() , writable = false , enumerable = true , configurable = false 
*/ 
	 
	var Pierre = Object.dvjhClone( iPersonne ); 
 
	Pierre.prenom = "Pierre"; 
	Pierre.nom = "Dupond"; 
	 
	var Daniel = Object.dvjhClone( iPersonne ); 
	 
	Daniel.init( "Daniel", "Hagnoul", 999 ); 
 
	console.log(  Object.keys( Pierre ), Pierre ); 
	console.log(  Object.keys( Daniel ), Daniel ); 
	 
	console.log( Pierre.prenom, Pierre.nom, Pierre.numero, Pierre.adresse ); 
	console.log( Daniel.prenom, Daniel.nom, Daniel.numero, Daniel.adresse ); 
 
	console.log( "iPersonne.says() : ", iPersonne.says() ); 
	console.log( "Pierre.says() : ", Pierre.says() ); 
	console.log( "Daniel.says() : ", Daniel.says() ); 
	 
	Daniel.name = Daniel.prenom; 
	 
	console.log( "Daniel.says() : ", Daniel.says() ); 
	 
/* 
Résultat dans Firebug : 
["name", "prenom", "nom", "adresse", "numero", "init"] Object { name="Henri", prenom="Pierre", nom="Dupond", more...} 
["name", "prenom", "nom", "adresse", "numero", "init"] Object { name="Henri", prenom="Daniel", nom="Hagnoul", more...} 
Pierre Dupond 0 J'habite en Belgique 
Daniel Hagnoul 999 J'habite en Belgique 
iPersonne.says() : je m'appelle Henri 
Pierre.says() : je m'appelle Henri 
Daniel.says() : je m'appelle Henri 
Daniel.says() : je m'appelle Daniel 
*/ 
} 
catch( evt ){ 
	console.log( evt.message ); 
} 
Test n° 2 :
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.
"use strict"; 
 
var Daniel = Object.create( {}, { 
	"_nom" : { 
		value : "Hagnoul", 
		writable : true 
	}, 
	"_prenom" : { 
		value : "Daniel", 
		writable : true 
	}, 
	"says" : { 
		value : function(){ 
			return "Je m'appelle " + this._prenom + " " + this._nom + "."; 
		}, 
		enumerable : true 
	} 
}); 
 
var Pays = Object.create( {}, { 
	"_pays" : { 
		value : "Belgique", 
		writable : true 
	}, 
	"capitale" : { 
		value : "Bruxelles", 
		writable : true, 
		enumerable : true 
	}, 
	"propagande" : { 
		value : function(){ 
			return "Mon pays (" + this._pays + ") est le plus beau du monde !"; 
		}, 
		enumerable : true 
	} 
}); 
 
try { 
	var Moi = Object.dvjhExtendAndProperties( Daniel, Pays, { 
		"fleurs" : { 
			value : "Tulipes", 
			writable : true, 
			enumerable : true 
		} 
	}); 
	 
	console.log( Moi ); 
	console.log( Object.keys( Moi ) ); 
	 
	Object.getOwnPropertyNames( Moi ).forEach( function( key ){ 
		var props = Object.getOwnPropertyDescriptor( Moi, key ); 
		 
		console.log( "Moi : key = ", key, ", value = ", props.value,  
						", writable = ", props.writable,  
						", enumerable = ", props.enumerable,  
						", configurable = ", props.configurable ); 
	}); 
	 
	console.log( Moi.says(), Moi.propagande() ); 
 
/* 
Résultat dans Firebug : 
Object { capitale="Bruxelles", fleurs="Tulipes", says=function(), more...} 
["says", "capitale", "propagande", "fleurs"] 
Moi : key = _nom , value = Hagnoul , writable = true , enumerable = false , configurable = false 
Moi : key = _prenom , value = Daniel , writable = true , enumerable = false , configurable = false 
Moi : key = says , value = function() , writable = false , enumerable = true , configurable = false 
Moi : key = _pays , value = Belgique , writable = true , enumerable = false , configurable = false 
Moi : key = capitale , value = Bruxelles , writable = true , enumerable = true , configurable = false 
Moi : key = propagande , value = function() , writable = false , enumerable = true , configurable = false 
Moi : key = fleurs , value = Tulipes , writable = true , enumerable = true , configurable = false 
Je m'appelle Daniel Hagnoul. Mon pays (Belgique) est le plus beau du monde ! 
*/ 
} 
catch( evt ){ 
	console.log( evt.message ); 
} 
Test n° 3 :
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.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
"use strict"; 
 
var iEmployee = Object.create( {}, { 
	"_name" : { 
		value : "", 
		writable : true 
	}, 
	"_dept" : { 
		value : "general", 
		writable : true 
	}, 
	"name" : { 
		get : function(){ 
			return this._name; 
		}, 
		set : function( value ){ 
			this._name = value; 
		}, 
		enumerable : true 
	}, 
	"dept" : { 
		get : function(){ 
			return this._dept; 
		}, 
		set : function( value ){ 
			this._dept = value; 
		}, 
		enumerable : true 
	} 
}); 
 
var iManager = Object.dvjhCloneAndProperties( iEmployee, { 
	"_reports" : { 
		value : [], 
		writable : true 
	}, 
	"reports" : { 
		get : function(){ 
			return this._reports.concat(); 
		}, 
		set : function( value ){ 
			if ( Array.isArray( value ) ){ 
				this._reports = value; 
			} 
		}, 
		enumerable : true 
	} 
}); 
 
var iWorkerBee = Object.dvjhCloneAndProperties( iEmployee, { 
	"_projects" : { 
		value : [], 
		writable : true 
	}, 
	"projects" : { 
		get : function(){ 
			return this._projects.concat(); 
		}, 
		set : function( value ){ 
			if ( Array.isArray( value ) ){ 
				this._projects = value; 
			} 
		}, 
		enumerable : true 
	} 
}); 
 
var iSalesPerson = Object.dvjhCloneAndProperties( iWorkerBee, { 
	"_quota" : { 
		value : 100, 
		writable : true 
	}, 
	"quota" : { 
		get : function(){ 
			return this._quota; 
		}, 
		set : function( value ){ 
			this._quota = value; 
		}, 
		enumerable : true 
	} 
}); 
 
iSalesPerson.dept = "sales"; 
 
var iEngineer = Object.dvjhCloneAndProperties( iWorkerBee, { 
	"_machine" : { 
		value : "", 
		writable : true 
	}, 
	"machine" : { 
		get : function(){ 
			return this._machine; 
		}, 
		set : function( value ){ 
			this._machine = value; 
		}, 
		enumerable : true 
	} 
}); 
 
iEngineer.dept = "engineering"; 
 
try { 
	console.log( iEmployee, iManager, iWorkerBee ); 
	console.log( Object.keys( iEmployee ), Object.keys( iManager ), Object.keys( iWorkerBee ) ); 
	 
	Object.getOwnPropertyNames( iEmployee ).forEach( function( key ){ 
		var props = Object.getOwnPropertyDescriptor( iEmployee, key ); 
		 
		console.log( "iEmployee : key = ", key, ", value = ", props.value,  
						", writable = ", props.writable,  
						", enumerable = ", props.enumerable,  
						", configurable = ", props.configurable ); 
	}); 
	 
	Object.getOwnPropertyNames( iManager ).forEach( function( key ){ 
		var props = Object.getOwnPropertyDescriptor( iManager, key ); 
		 
		console.log( "iManager : key = ", key, ", value = ", props.value,  
						", writable = ", props.writable,  
						", enumerable = ", props.enumerable,  
						", configurable = ", props.configurable ); 
	}); 
	 
	Object.getOwnPropertyNames( iWorkerBee ).forEach( function( key ){ 
		var props = Object.getOwnPropertyDescriptor( iWorkerBee, key ); 
		 
		console.log( "iWorkerBee : key = ", key, ", value = ", props.value,  
						", writable = ", props.writable,  
						", enumerable = ", props.enumerable,  
						", configurable = ", props.configurable ); 
	}); 
	 
	console.log( iSalesPerson, iEngineer ); 
	console.log( Object.keys( iSalesPerson ), Object.keys( iEngineer ) ); 
	 
	Object.getOwnPropertyNames( iSalesPerson ).forEach( function( key ){ 
		var props = Object.getOwnPropertyDescriptor( iSalesPerson, key ); 
		 
		console.log( "iSalesPerson : key = ", key, ", value = ", props.value,  
						", writable = ", props.writable,  
						", enumerable = ", props.enumerable,  
						", configurable = ", props.configurable ); 
	}); 
	 
	Object.getOwnPropertyNames( iEngineer ).forEach( function( key ){ 
		var props = Object.getOwnPropertyDescriptor( iEngineer, key ); 
		 
		console.log( "iEngineer : key = ", key, ", value = ", props.value,  
						", writable = ", props.writable,  
						", enumerable = ", props.enumerable,  
						", configurable = ", props.configurable ); 
	}); 
 
/* 
Résultat dans Firebug : 
Object { dept="general", name=""} Object { dept="general", reports=[0], name=""} Object { dept="general", projects=[0], name=""} 
["name", "dept"] ["name", "dept", "reports"] ["name", "dept", "projects"] 
iEmployee : key = _name , value = , writable = true , enumerable = false , configurable = false 
iEmployee : key = _dept , value = general , writable = true , enumerable = false , configurable = false 
iEmployee : key = name , value = undefined , writable = undefined , enumerable = true , configurable = false 
iEmployee : key = dept , value = undefined , writable = undefined , enumerable = true , configurable = false 
iManager : key = _name , value = , writable = true , enumerable = false , configurable = false 
iManager : key = _dept , value = general , writable = true , enumerable = false , configurable = false 
iManager : key = name , value = undefined , writable = undefined , enumerable = true , configurable = false 
iManager : key = dept , value = undefined , writable = undefined , enumerable = true , configurable = false 
iManager : key = _reports , value = [] , writable = true , enumerable = false , configurable = false 
iManager : key = reports , value = undefined , writable = undefined , enumerable = true , configurable = false 
iWorkerBee : key = _name , value = , writable = true , enumerable = false , configurable = false 
iWorkerBee : key = _dept , value = general , writable = true , enumerable = false , configurable = false 
iWorkerBee : key = name , value = undefined , writable = undefined , enumerable = true , configurable = false 
iWorkerBee : key = dept , value = undefined , writable = undefined , enumerable = true , configurable = false 
iWorkerBee : key = _projects , value = [] , writable = true , enumerable = false , configurable = false 
iWorkerBee : key = projects , value = undefined , writable = undefined , enumerable = true , configurable = false 
Object { dept="sales", projects=[0], quota=100} Object { dept="engineering", projects=[0], name="", more...} 
["name", "dept", "projects", "quota"] ["name", "dept", "projects", "machine"] 
iSalesPerson : key = _name , value = , writable = true , enumerable = false , configurable = false 
iSalesPerson : key = _dept , value = sales , writable = true , enumerable = false , configurable = false 
iSalesPerson : key = name , value = undefined , writable = undefined , enumerable = true , configurable = false 
iSalesPerson : key = dept , value = undefined , writable = undefined , enumerable = true , configurable = false 
iSalesPerson : key = _projects , value = [] , writable = true , enumerable = false , configurable = false 
iSalesPerson : key = projects , value = undefined , writable = undefined , enumerable = true , configurable = false 
iSalesPerson : key = _quota , value = 100 , writable = true , enumerable = false , configurable = false 
iSalesPerson : key = quota , value = undefined , writable = undefined , enumerable = true , configurable = false 
iEngineer : key = _name , value = , writable = true , enumerable = false , configurable = false 
iEngineer : key = _dept , value = engineering , writable = true , enumerable = false , configurable = false 
iEngineer : key = name , value = undefined , writable = undefined , enumerable = true , configurable = false 
iEngineer : key = dept , value = undefined , writable = undefined , enumerable = true , configurable = false 
iEngineer : key = _projects , value = [] , writable = true , enumerable = false , configurable = false 
iEngineer : key = projects , value = undefined , writable = undefined , enumerable = true , configurable = false 
iEngineer : key = _machine , value = , writable = true , enumerable = false , configurable = false 
iEngineer : key = machine , value = undefined , writable = undefined , enumerable = true , configurable = false 
*/ 
		 
		var Pierre = Object.dvjhClone( iEngineer ); 
		 
		Pierre.name = "Dupond Pierre"; 
		Pierre.machine = "Trucspace"; 
		Pierre.projects = [ "space1" ]; 
		 
		console.log( Pierre ); 
		console.log( Object.keys( Pierre ) ); 
		 
		Object.getOwnPropertyNames( Pierre ).forEach( function( key ){ 
			var props = Object.getOwnPropertyDescriptor( Pierre, key ); 
			 
			console.log( "Pierre : key = ", key, ", value = ", props.value,  
							", writable = ", props.writable,  
							", enumerable = ", props.enumerable,  
							", configurable = ", props.configurable ); 
		}); 
 
/* 
Résultat dans Firebug : 
Object { name="Dupond Pierre", dept="engineering", projects=[1], more...} 
["name", "dept", "projects", "machine"] 
Pierre : key = _name , value = Dupond Pierre , writable = true , enumerable = false , configurable = false 
Pierre : key = _dept , value = engineering , writable = true , enumerable = false , configurable = false 
Pierre : key = name , value = undefined , writable = undefined , enumerable = true , configurable = false 
Pierre : key = dept , value = undefined , writable = undefined , enumerable = true , configurable = false 
Pierre : key = _projects , value = ["space1"] , writable = true , enumerable = false , configurable = false 
Pierre : key = projects , value = undefined , writable = undefined , enumerable = true , configurable = false 
Pierre : key = _machine , value = Trucspace , writable = true , enumerable = false , configurable = false 
*/ 
} 
catch( evt ){ 
	console.log( evt.message ); 
} 
 

Valid XHTML 1.0 TransitionalValid CSS!


Creative Commons License : Attribution-Share Alike 2.0 Belgium

Mention obligatoire : "Auteur : Hagnoul Daniel (https://www.developpez.net/forums/u285162/danielhagnoul/)"