¶
Feuille 3
2022
Définir des objects javascript pour représenter la pizza « basique » à 8 euros cinquante, dont les ingredients sont «sauce tomate»,«mozzarella» et «jambon», et la pizza « bbq » à 9 euros cinquante, dont les ingredients sont « Râpé » , « oignons » , « poulet» , « oignons » et « sauce barbecue ».
:::solution ### Solution
let piz1=
{nom:"basique",
prix:8.50,
ingredients:["sauce tomate","mozzarella","jambon" ]
}
let piz2={
nom:'bbq',
prix:9.5,
ingredients:["Râpé","oignons","poulet","oignons","sauce barbecue"]
}
Proposer une fonction creerPizza
pour créer un objet
pizza, a partir d'un nom d'un prix et d'une liste d'ingredients.
Puis l'utiliser pour créer une pizza « basquaise » à « 8 euros 90 » dont
les ingredients sont « Râpé » « oignons » « poivrons » « poulet ».
function creerPizza(nom,prix,ingredients){
return {
nom:nom,
prix:prix,
ingredients:ingredients
}
}
let piz3=creerPizza("basquaise",8.90,["Râpé","oignons","poivrons","poulet"])
Proposer un constructeur ou une classe pour les pizzas. Puis l'utiliser pour créer une pizza « frenchy » à « 9 euros » dont les ingredients sont « Râpé » « camembert » « herbes de Provence » « huile d'olive ».
function Pizza(nom,prix,ingredients){
this.nom=nom;
this.prix=prix,
this.ingredients=ingredients
}
//ne pas oublier le new !!!
let piz4=new Pizza("frenchy",9,["Râpé","camembert","herbes de Provence","huile d'olive"])
ou avec une classe ( sans méthode, autres que le constructeur, on n'ira pas tres loin mais c'est pour voir la syntaxe )
class Pizza {
nom
prix
ingredientsconstructor(nom,prix,ingredients){
this.nom=nom,
this.prix=prix,
this.ingredients=ingredients
}
}
let piz4=new Pizza("frenchy",9,["Râpé","camembert","herbes de Provence","huile d'olive"])
Une commande de pizza, a un nom, une adresse et la liste des pizzas commandées On peut lui ajouter des pizzas, ou demander le prix total.
Proposer une classe pour représenter une commande.
class Commande{
constructor(nom,adresse,liste){
this.nom=nom;
this.adresse=adresse
this.liste=liste||[] //si pas de liste alors tableau vide
}ajouter(pizza){
this.liste.push(pizza);
}calculerPrix(){
let res=0;
for(let i=0;i<this.liste.length;i++){
+=this.liste[i].prix
res
}return res;
}
}
> let commande1=new Commande("pons","paris",[piz1,piz2])
undefined
> commande1.calculerPrix()
18
>
Vous voulez garder la trace des livres que vous avez lus et de ceux que vous voulez lire.
Pour cela, créez un tableau d'objets livre , où chaque objet décrit
un livre et possède 3 propriétés le titre , l'auteur et
déjàLu
(un booléen indiquant si vous l'avez déjà lu).
let meslivres = [
titre: 'Cours de calcul différentiel',
{auteur: 'Henri Cartan',
deja: false
,
}titre: 'Analyse hilbertienne',
{auteur: 'Laurent Schwartz ',
deja: false
,
}titre: 'Algèbre linéaire et géométrie élémentaire',
{auteur: 'Jean Dieudonné ',
deja: true
,
}titre: 'Théorie algébrique des nombres ',
{auteur: 'Pierre Samuel ',
deja: true
};
]
function afficheLivre(livres){
for (let i = 0; i < livres.length; i++) {
let livre = livres[i];
let infoLivre = '"'+livre.titre + '" de ' + livre.auteur;
if (livre.deja) {
console.log('Vous avez déjà lu ', infoLivre);
else {
} console.log('Vous devez encore lire', infoLivre);
}
}
}afficheLivre(meslivres)
Pour aller plus loin, vous pouvez aussi définir une classe
livre
et une classe listeDeLivre
, ajouter une
méthode qui sépare les livres lus des autres et produit 2 listes,
etc..
Il s'agit de définir un objet chronometre
avec deux
méthodes. - demarrer
qui démarre le chronomètre -
arreter
qui l’arrête et renvoie le nombre de millisecondes
écoulées depuis le démarrage.
Si le chronomètre n'est pas démarré elle ne fait rien.
Sinon il attend qu'on lui demande de s’arrêter.
Quand on l’arrête, il affiche le temps écoulé depuis le démarrage
On pourra utiliser Date.now()
qui renvoie le nombre de
millisecondes depuis le 1er Janvier 1970.
>chronometre.start()
undefined
> chronometre.end() // presque 2 seconde après
1943
>
let chronometre={
estDemmarre:false,
current:undefined,
demarrer : function (){ this.estDemmarre=true; this.current=Date.now(); },
arreter : function (){ if(this.estDemmarre){
//sinon on ne fait rien
this.estDemmarre=false;
return Date.now()-this.current; }
}
}
On peut l'utiliser pour comparer le temps d'execution de 2 fonctions. il suffit de comparer les resultat de :
.start();f1();chronometre.end()
chronometre.start();f2();chronometre.end() chronometre
Écrire une fonction pour convertir un objet en une liste de paires.
let p={nom:"Marx",prenom:"Karl"}
> objet2List2paires(p)
'nom', 'Marx' ], [ 'prenom', 'Karl' ] ] [ [
function objet2List2paires(o){
let res=[];
for (let key in o){
.push([key,o[key]]);
res
}return res;
}
L'objectif est ici de modéliser (de façon rudimentaire) un compte en
banque. Dans premiere version le compte un compte a juste un montant et
deux méthode, ajouter
et retirer
qui font
varier le montant.
On ne peut retirer plus que le montant present sur le compte.
Avec une classe
class Compte {
montant// Constructeur
constructor(montantDeDepart) {
this.montant=montantDeDepart ||0; //0 si pas d'argument
}
// Une méthode qui crédite le compte
ajouter(somme) {
this.montant = this.montant + somme;
return this.montant
}// une methode pour retirer de l'argent
retirer(somme){
//on verifie qu'il y a assez
if(somme > this.montant){console.log("retrait max :"+this.montant);
return
}this.ajouter(- somme)
return this.montant
}
}
=new Compte(100); c
Avec une fonction de creation
let baseCompte={
ajouter: function(somme) {
this.montant = this.montant + somme;
return this.montant
,
}// une methode pour retirer de l'argent
retirer: function (somme){
//on verifie qu'il y a assez
if(somme > this.montant){
console.log("retrait max :"+this.montant);
return
}this.ajouter(- somme)
return this.montant
};
}
function creerCompte(montantDeDepart){
let o=Object.create(baseCompte)
.montant=montantDeDepart||0;
oreturn o;
}
=creerCompte(50); d
Définir une classe CompteAvecDécouvert
qui hérite de
compte mais qui autorise un découvert d'un montant maximum qui peut être
fixer par une méthode fixerDécouvert
class CompteAvecDécouvert extends Compte {
decouvert// Constructeur
constructor(montantDeDepart,decouvert) {
super(montantDeDepart)
this.decouvert=decouvert ||0; //0 si pas d'argument
}fixerDecouvert(somme){
this.decouvert=somme;
}
//on redefini retirer
retirer(somme){
//on verifie qu'il y a assez
if(somme > this.montant+this.decouvert){console.log("retrait max :"+(this.montant+this.decouvert));
return
}//ajouter est celui défini dans compte
this.ajouter(- somme)
return this.montant
} }
ou si on crée avec des fonctions:
On peut définir un Compte et le mettre comme prototype du nouvel
objet compteAvecDecouvert
mais on veut éviter de le faire à
chaque creation. Tous les comptes avec decouvert autorisé doivent
partager le même prototype.
Pour cela on va creer une fermeture avec une fonction appliquée immédiatement
let CreerCompteAvecDecouvert= (function (){
let compte=creerCompte(); // visible que dans la fonction
let proto=Object.create(compte); // visible que dans la fonction
.retirer =function (somme){
proto//on verifie qu'il y a assez
if(somme > this.montant+this.decouvert){console.log("retrait max :"+(this.montant+this.decouvert));
return
}//ajouter est celui défini dans compte
this.ajouter(- somme)
return this.montant
}return function (montant,decouvert){
=Object.create(proto);
o.montant=montant;
o.decouvert=decouvert;
oreturn o;
}
; })()
Les variables compte
et proto
ne sont
visibles que dans la fonction CreerCompteAvecDecouvert
.
Quand cette fonction est appliqué (avec les ()
à la fin)
cela renvoie une fonction anonyme à 2 arguments, dans laquelle
compte
et proto
ont été encapsulées et peuvent
être utilisées.
Il n'y a aucun moyen d'acceder a ces variables par ailleurs, mais
rien n’empêche de créer d'autre variables compte
ou
proto
proto dans le contexte externe à
CreerCompteAvecDecouvert
Elle n'aurtont aucun liens (et donc aucun risque de conflit) avec les
variables définies localement dans CreerCompteAvecDecouvert
et « encapsulé » par la fonction renvoyée.
Écrivez une fonction JavaScript pour imprimer toutes les méthodes d'un objet JavaScript. On pourra utiliser getOwnPropertyNames pour obtenir un tableau de de toutes les propriétés d'un objet. Il s'agit de retenir celles qui ont une valeur fonctionnelle.
On peut éventuellement utiliser la fonctionnelle filter pour filtrer les propriétés; on peut aussi faire une boucle.
function ToutesLesMethods(obj) {
return Object.getOwnPropertyNames(obj).filter(function(property) {
return typeof obj[property] == "function";
;
})
}
> ToutesLesMethods(Math)
['abs', 'acos', 'acosh', 'asin',
'asinh', 'atan', 'atanh', 'atan2',
'ceil', 'cbrt', 'expm1', 'clz32',
'cos', 'cosh', 'exp', 'floor',
'fround', 'hypot', 'imul', 'log',
'log1p', 'log2', 'log10', 'max',
'min', 'pow', 'random', 'round',
'sign', 'sin', 'sinh', 'sqrt',
'tan', 'tanh', 'trunc'
]
ou avec une boucle
function ToutesLesMethods(obj) {
let res=[];
let tabMethodes=Object.getOwnPropertyNames(obj);
for(let i=0;i<tabMethodes.length;i++){
if(typeof obj[tabMethodes[i]] == "function"){
.push(tabMethodes[i])
res
}
}return res;
}