1. Zaghir Y Javascipt Page 1 sur 40
Table des matières
JavaScript ................................................................................................................................................ 3
Debug du code .................................................................................................................................... 4
Syntaxe................................................................................................................................................ 4
Mode strict.......................................................................................................................................... 5
Les points virgules............................................................................................................................... 5
Semicolon insertion............................................................................................................................ 5
La portée de la variable ou Scope ...................................................................................................... 6
Les types.............................................................................................................................................. 6
Autoboxing.......................................................................................................................................... 7
Comparaisons ..................................................................................................................................... 7
Les objets ............................................................................................................................................ 8
Les prototypes :........................................................................................................................ 10
Les tableaux ...................................................................................................................................... 12
Fonctions :......................................................................................................................................... 17
Définition de la fonction :................................................................................................................. 17
Fonctions internes ............................................................................................................................ 18
First class objects :............................................................................................................................ 18
Exemple de fonction factorisation : calcul de factoriel................................................................... 19
Appel de fonction ............................................................................................................................. 21
4 facons d’invoquer une fonction .................................................................................................... 21
2 ème façon : comme méthode ................................................................................................... 21
3 ème facon : comme constructeur ............................................................................................. 24
4 ème façon : call ou apply........................................................................................................... 27
ES6/2015 : class................................................................................................................................. 27
Closure .............................................................................................................................................. 29
Anonymous wrapper........................................................................................................................ 32
Pattern "Module" ............................................................................................................................. 33
Operateurs && et ||......................................................................................................................... 35
Opérateur ||..................................................................................................................................... 36
Boucles for et for…in ........................................................................................................................ 36
Exceptions :....................................................................................................................................... 37
JS patterns......................................................................................................................................... 39
Duck typing codage du canard ......................................................................................................... 39
Mixing Extend ................................................................................................................................... 40
2. Zaghir Y Javascipt Page 2 sur 40
Configuration object......................................................................................................................... 40
Promesses ......................................................................................................................................... 40
3. Zaghir Y Javascipt Page 3 sur 40
Faits le 04/05/2016
JavaScript , version ECMAScript 5.1
JavaScript
JavaScript est :
un langage orienté objet sans classes
un langage non typé vers une fort composante fonctionnelle
fonctionnel, on peut manipuler des fonctions qui sont des vrais objets
Quel JavaScript :
ECMAScript 5.1 / juin 2011
mode strict
getters / setters
JSON
Etc
ECMAScript 5 2015 / mi 2015
Classes
Modules
Promesses
Ets …
Support ES6 http://kangax.github.io/compact-table/es6
Es6 c’est les nouvelles normes pour JavaScript donc elle n’est pas encore supporté nativement par
tous les navigateurs
Pour résoudre le problème de compatibilité entre ES6 et ES5, on utilise les copilers ou les polyfiles
comme Babel traceur, typscripte + core.js
4. Zaghir Y Javascipt Page 4 sur 40
Debug du code
Syntaxe
Le mode "use strict"
Déclarer en tout début de fichier ou début de la fonction.
5. Zaghir Y Javascipt Page 5 sur 40
Javascript va être plus rigoureux pour la syntaxe
Mode strict
Permet de signaler davantage d’erreurs (fail-fast)
Ex : variable non déclarée
Ne transforme plus this en objet
Plus d’objet global window à la place de undefine
Impose
L’unicité des propriétés dans un objet littéral
L’unicité des noms d’arguments dans une fonction
Les déclarations de fonctions au plus haut niveau d’un script ou une fonction
L déclaration des variable c’est avec var , si on initialise pas la variable sa valeur est undefine
La fonction en JavaScript return toujours une valeur , si on ne retourne pas de valeur le return
est égale à undefine
Les points virgules
Les instructions se terminent par un point-virgule. Par défaut JavaScript ajoute un point-virgule
automatiquement pour chaque fonction
Ex :
Semicolon insertion
Règles d’insertion automatique des ; :
En fin de ligne, de fichier, ou avant une }
Seulement si token suivant crée une erreur de syntaxe
"use strict" ;
function muliplicative(){
var left =unary() ;
var token ;
while(token = expect('*','/' ,'%')){
left =binaryFn(left, token.fn , unnary()) ;
}
return left ;
}
'use strict'
function testReturn (argument) {
return
["un" ,
"deux" ,
true];
//return { "parma1":"p1"
,"parm2":"p2" ,"parma3":"p" }
}
console.log(testReturn("Youssef")) ;
JavaScript Ajoute ; après
le return resulat
undefine
'use strict'
function testReturn (argument) {
return["un" ,
"deux" ,
true];
//return { "parma1":"p1"
,"parm2":"p2" ,"parma3":"p" }
}
console.log(testReturn("Youssef")) ;
Après le return un
tableau à retourner
resulat tableau
6. Zaghir Y Javascipt Page 6 sur 40
Jamais dans l’entête d’une boucle for
Jamais quand le ; crée une instruction vide
Insertion systématique là où une fin de ligne est interdite , car elle peut couper l’instruction par
une :
PostfixExpersion
LiftHandSideExpersion[no LineTeminator here] ++ / --
ContinueStatement & BreakStatement :
Continue / breack [no LineTerminator here] Identifier ;
ReturnStatement:
Return [no Lineterminator here] Expression ;
L’instruction sera sur la meme ligne que return si no undefine
ThrowStatement:
Throw[no Lineterminator here] Expression ;
L’instruction et throw sur la même ligne ;
La portée de la variable ou Scope
Portée des variables en JavaScript : "function scope"
Une varible est déclarée pour toute la fonction qui la contient
Même avant la ligne où se trouve le mot clef var
Contrairement au "block scope" de Java :{}
JavaScript fait un premier parce pour le code de la fonction, repère toutes les variables déclarés et il
le déclare dès le début
Une variable déclarée hors de toute fonction devient un propriété du scope global
Dans le navigateur web le scope global est accessible sous le nom de window
La fonction f est une fonction global en la trouve comme un propriété dans l’objet window.f
Tous ce qui est global il faut l’évité absolument parce que le scope globale et commun à tous les
fichiers JavaScript de l’application, les fichiers de l’application partage le même objet global window
c’est possible d’avoir des collision entre les fichiers ou les fonctions ou les variables déclarées
Les types
Dans JavaScript il y a les objets et les types primitifs
Boolean , numbers , string , undefined , null
undefined : si pas de valeur affectée (pas de valeur dans la variable )
null : affecté explicitement, pour signifier l’absence d’objet
function f(array){
// i , element , label sont déjà déclarées ici
for(var i = 0 ; i < array.length ; i++){
var element = array[i] ;
if(element.max > 0 ){
var label = element.label ;
//...
}
}
}
JavaScript parce la fonction et elle va
déclarer les variable au début de fonction
function f(array){
var i ; var element ; var labe ;
for(i …..
7. Zaghir Y Javascipt Page 7 sur 40
un seul type numérique, sur 8 octets (décimale pas très précis, ex :
0.2+0.3 = 0.3 000000000004) à cause du stockage des nombres binaires
exponentiel
ex : 0.1+.03 == 0.3 retun false
pas de type caractère
type primitif
pas de référence, c’est seulement une valeur
passage par valeu( copie de la valeur )
objet
passage par référence
Autoboxing
Les booléens, nombres et chaines de caractères sont :
immuables
convertis à la volée en objet (Boolean, Number, String) quand c’est nécessaire
Au moment où on demande une propriété d’un type primitif, JavaScript crée un objet number avec la
même valeur ou string et cet objet number n’est pas conservé, dans la variable sa reste un nombre
primitif mais au moment de l’appelle d’une méthode comme ici length l’objet créer et on peut
utiliser la méthode
Ne pas utiliser ou créer explicitement les types des Objets Boolean, Number, String car sa
cause de problème de comparaison ou typeOf …
Comparaisons
=== comparaison stricte (sans conversion)
true pour deux données primitives du même type et de même valeur c’est-à-dire :
true pour deux booléens (primitifs) égaux
true pour deux nombres (primitifs) égaux
true pour deux chaines de caractères (primitives) égaux
true pour deux références au même objet
false dans tous les autres cas
== comparaison avec conversion automatique de type
var n = 5 ;
n.toString();
var s = "hello" ;
s.length ;
var a = new String('YOUSSEF') ;
var b = new String('YOUSSEF') ;
a == 'YOUSSEF' ; // true
a === 'YOUSSEF' ; // false
a == b ;// false
a === b ; // false
typeOf 'YOUSSEF' ; // "string"
typeOf a ; // "object
8. Zaghir Y Javascipt Page 8 sur 40
s’il y a un opérande primitif
null == undefined
si un opérande number ou boolean => convertit tout en number après
compare
si un opérande string => convertit tout en string après compare
pour deux objets : compare les références
Les objets
Les objets JavaScript sont des maps (clefs /valeurs) , pas de classes en JavaScript
clef : chaine de caractères = nom de la propriété
valeur quelconque (non typé)
Pas de notion de visibilité : toutes les propriétés sont publiques , n’importe objet peut accéder à une
propriété de l’autre
2 façons d’accéder à une valeur d’une propriété
obj["clef"] ce n’est pas un tableau c’est une propriété , ca marche toujours
obj. clef
Nombre ou
booléen primitif
?
Comparaison avec conversion de type
(==)
Convertit
tout en
nombre
Chaine primitif
? Convertit
tout en
chaine
Compare les
reference des objets
OUI
OUI
NON
NON
0 == false ;
1 == true ;
"1" == true ;
2 == "2" ;
1 == new Number(1) ;
new Number(1) != new Number(1) ;
"" == 0 ;
false == "" ;
false == [] ;
false != {} ;
[] == "" ;
["2"] == 2 ;
// string -> number
"" == 0 ;
// Array -> number
["2"] == 2 ;
[""] == 0 ;
[""] == false ;
["2"] != [2] ;
// Array -> string
["2" , 3 ] == "2,3" ;
// Non transitif
"1" == true ;
"01" == true ;
"01" != "1" ;
9. Zaghir Y Javascipt Page 9 sur 40
Notation entre crochets :
toujours possible, même avec un nom de propriété dynamique
n’importe quelle chaine est autorisée comme nom de propriété
Notation avec un point :
possible pour un nom de propriété en dur, qui est un identifiant valide
Créer un objet avec {…} ;
Créer des objets imbriqués :
Propriété de l’objet :
Les objets n’ont pas une structure figée
Ajouter ou modifier une propriété :
Si la propriété existe elle va être modifié, si elle n’existe pas
elle va être créée
Supprimer une propriété
La propriété est retirée carrément de l’objet
obj['a.b'] ;
obj[''] ;
Obj.a.b // N’
a pas le meme
sens !
var DATE_FORMATS = {
yyyy : dateGetter('FullYear' , 4) ,
yy : dateGetter('FullYear' , 2 , 0 , true) ,
MM : dateGetter('Month' , 2 , 1)
};
var book ={
title : "Javascript : version 1",
author : "Youssef" ,
publisher : "O'Reilly" ,
details : {
"ISBN-10" : "1234567890" ,
"ISBN-13" : "999-1234567890" ,
page :178
}
}
Détail :objet imbriqué
angular.element = jqLite ;
dst[key] =src[key] ;
Delete params[kye];
Delete event.stopPropagation ;
10. Zaghir Y Javascipt Page 10 sur 40
This représente l’objet ou la
fonction elle est appelée
Si on n’a pas mi this ca ne
marche pas car on javascript il
n’y a pas de classe ou objet
courant, et dans le code il n y
a pas de variable (var) local
firstname
Propriété de l’objet :
Les prototypes :
Recherche d’une propriété get
Dans l’objet courant
Puis dans son prototype
Puis dans le prototype de son prototype
Puis dans le prototype du son prototype du son prototype …
Un prototype d’un objet un autre objet quelque qu’encre
Si on cherche une propriété dans un objet et que l’on trouve pas javascript cherche dans le prototype
puis si elle ne le trouve pas elle cherche dans le prototype du prototype …
'use strict'
var me = {
firstName : "Youssef" ,
lastName : "Souffoun" ,
fullName : function(){
return this.firstName + " " +
this.lastName ;
}
};
console.log(me.fullName());
'use strict'
var me = {
firstName : "Youssef" ,
lastName : "Souffoun" ,
fullName : function(){
return me.firstName + " " +
me.lastName ;
}
};
var person = me ;
me = null ;
console.log(person.fullName());
Utilisation nom de la variable
Le résultat est null
'use strict'
var me = {
firstName : "Youssef" ,
lastName : "Souffoun" ,
fullName : function(){
return this.firstName + " " +
this.lastName ;
}
};
var person = me ;
me = null ;
console.log(person.fullName());
Utilisation du mot this
Le résultat est le nom de la
personne
11. Zaghir Y Javascipt Page 11 sur 40
Affectation d’une valeur à une propriété (Set)
Modifie ou crée la propriété toujours dans l’objet local
Même si c’était une propriété hérité d’un prototype
Les prototypes ne sont pas utilisées ils sont créée uniquement dans l’objet courant
Chaine des prototypes
Accéder au prototype d’un objet :
ES5 : Objet.getPrototypeOf (obj)
Pas standard : obj.__proto__
Racine de la chaine des prototypes : Object.prototype
Créer un objet avec un certain prototype :
Object.prototype
toString
Array.prototype
forEach
myArray
length
Lecture : héritage
myArray
length
foreach
toString
La méthode toString
n’est pas défini dans
myArray, JavaScript va
chercher dans
Array.prototype , elle ne
le trouve pas elle
cherche dans le
Object.prototype ,elle le
trouve
Ce mécanise et en mode
lecture
Object.prototype
toString
Array.prototype
forEach
myArray
length
toString
Ecriture : en local
myArray.toString = ….
Prototype : fonction qu on écrit une seul fois
.elle sera partagé par tout le monde et il est
on lecture seule
Object.getPrototypeOf(Object.prototype) ; // null
var .ogj = Object.create(proto) ;
12. Zaghir Y Javascipt Page 12 sur 40
Les tableaux
Les tableaux sont des objets JavaScript initialisé par […]
Comme tous les objets, ils ont des propriétés dont les noms sont des chaines de caractères , ils ne
sont pas typés
C’est un objet avec des clefs de type chaine de caractère
La réalité en JavaScript le tableau c’est objet qui va émuler le comportement d’un tableau
Certaines propriétés sont considérées comme des index numérique
Présentation texte canonique d’un entier positif
Index : "0" , "1" , "2" , "15"
Pas d’index : "-1" , "3.14" , "01"
Propriété length > plus grand index
Ajout d’un index trop grand : length est augmentée
Modification de length : les index trop grand sont supprimés
Pour modifier la taille il faut inserer un nombre entier positif
Il va les considérés comme des index positive
var emptyArray = [] ;
var a = ['this' , 'is' , 'an' , 'array' ] ;
a[1] ; // "is"
var a = ['this' , 'is' , 'an' , 'array'] ;
Object.keys(a) ; // ["0" , "1" , "2" , "3"]
a[1]; // "is"
a['1'] ; // "is"
a[8] = 'new' ;
a.length ; // 9
a.length = 2 ;
a ; // ["this" , "is"] ;
a.length = 0 ;
a ; // [] initialisation de tableau
13. Zaghir Y Javascipt Page 13 sur 40
Création du tableau et affiché le
deuxième élément
Afficher les index de l’objet a
Afficher la taille
Ajouter un élément dans l’index égal 8
Afficher l’objet a de type tableau, javascript a
ajouter 4 élément non saisie plus a[8]
Ajouter un élément dans l’index n’est pas un
entier positif, ici c’est un string
L’index de l’élément ajouté est affiché
La valeur de l’élément ajouté n’est pas
affichée , il faut indiqué l’index de l’élément.
C’est comme une hashMap(clé , valeur)
Supprimer l’élément 8 du tableau
Javascript ne va jamais diminué la taille
automatiquement , est ce qu’il va passer à 7
ou …
14. Zaghir Y Javascipt Page 14 sur 40
Méthodes modifiant le contenu du tableau
array.push(element1, element2, … elementN
ajoute en fin de tableau
array.pop() : enléve et renvoir le dernier élémpent
array.shift() : enléve et renvoie le premier élément
array.unshift(element1 , … elementN)
ajoute en début du tableau
array.splice( index , howMany , element1 …)
suprime et/ou ajoute des éléments
array.sort([compareFunction])
trie les éléments à l’intérieur du tableau
array.reverse()
inverse l’ordre des éléments d’un tableau
Ce qu’on va manipuler sur le tableau ce sont de méthodes qui sont héritées de leur prototypes qui
est un Array.prototype
L’objet array hérite la méthode push
Méthodes créant un nouveau tableau
array.concat(value1 , value2 , … , valueN)
renvoie un nouveau tableau égal à la concaténation du tableau courant et des tableaux
passés en paramètres (les arguments qui ne sont pas des tableaux sont ajoutés comme
des éléments) . Elle ne modifie pas le tableau en premier
array.slice(begin[, end])
Taille de tableau = 9
Réduire la taille de tableau à 4
éléments, les 4 éléments undifined
sont supprimés, "01" , "01000" ne
sont pas des nombres entité positif ,
ce qui ne sont pas considéré des
indexes numériques ne sont pas
modifié
Réduire la taille de tableau à 2 éléments.
Vider le tableau ;
15. Zaghir Y Javascipt Page 15 sur 40
renvoie une copie d’une portion du tableau courant depuis un index de debut vers un
index de fin
Méthodes ajoutées dans ECMAScript 5
array.indexOf(searchElement[,fromIndex])
Renvoie le premier index où l’élément est trouvé
array.lastIndexOf(searchElement[ , fromIndex])
renvoie le dernier index où l’élément est trouvé (de droit à gauch)
array.forEach(callback[, thisArg])
exécute une fonction callback pour chaque élément du tableau
array.every(callback[,thisObject])
renvoie true si tous les élément du tableau passent le test de fonction
array.some(callback[, thisObject])
renvoie true si au moins un des éléments du tableau passe le test de la fonction
callback
array.filter(callback[, thisObjet])
renvoie un tableau contenant les éléments qui passent le test de la fonction callback
array.map(callback[,thisArg])
renvoie un tableau avec le résultat de la fonction callback pour chacun des élément du
tableau de départ
array.reduce(callback[ , initialValue])
renvoie la valeur calculée en appliquant une fonction avec un accumulateur à chaque
élément du tableau , de gauche à droite
Un tableau avec 5 élément avec un qui
est impaire .Le tableau a une fonction
every qui test tous les éléments dans la
fonction callback et return un résultat
booléen
Changement de la valeur 5 par, le test est true
La fonction some du tableau return true si
au moins une condition est true
Fonction filter : récupérer une
liste de résultats après être
valider par la fonction callback
Fonction map : return une liste de
valeurs apres modification par la
fonction callback
Fonction
reduce : return
un seul resulat
Fonction reduce : on va définir le
premier élément du tableau
depuis lequel reduce va être
appliqué .Ici c’est }, 0) ;
16. Zaghir Y Javascipt Page 16 sur 40
'use strict'
var numbers =[17 , 35 , 46 , 73 , 20 , 52 , 67] ;
numbers.maxFor = function(){
var max ;
for(var i = 0 ; this.length ; i++){
if(max === undefined || this[i] > max){
max = this[i] ;
}
}
return max ;
};
console.log(numbers.maxFor());
il faut référencé l'objet sur lequel
on va faire appelle la fonction
maxFor par this : dire que c’est ce
tableau
Si on change la référence sur la
variable ça ne va plus marché :
maitre à la place de this nom de la
variable numbers
'use strict'
// la meme action avec forEach
var numbers =[17 , 35 , 46 , 73 , 20 , 52 , 67] ;
numbers.maxFor = function(){
var max ;
this.forEach(function(item){
if(max === undefined || item > max){
max = item ;
}
});
return max ;
};
console.log(numbers.maxFor());
Pour chaque élément courant
'use strict'
// la meme action avec reduce c'est plus simple
var numbers =[17 , 35 , 46 , 73 , 20 , 52 , 67] ;
numbers.maxReduce = function(){
return this.reduce(function(max , items){
return item > max ? item : max ;
});
};
console.log(numbers.maxReduce());
17. Zaghir Y Javascipt Page 17 sur 40
Fonctions :
Définition de la fonction :
FunctionDeclaration :
FunctionExpression :
Déclaration : FunctionDeclaration
mot-clef function au début d’instruction
nom est obligatoire
pas de valeur ne retourne pas
Expression : FunctionExpression
mot-clef function dans une expression (pas en début
d’instruction)
nom facultatif (utile pour une fonction récursive)
-valeur : l’objet fonction
function Identifier(FormalParameterList<opt>){
FunctionBody
}
function Identifier<opt>(FormalParameterList<opt>){
FunctionBody
}
function f(arg1 , arg2){
….
}
return function f(arg1 , arg2){
….
};
function f1(){ // Declaration
return function(){ // Expression
};
}
setTimeout(function(){ // Expression
// ….
}, 1000);
var f3 = function(){ // Expression
function f33(){ // Declaration
}
};
18. Zaghir Y Javascipt Page 18 sur 40
Fonctions internes
déclaration function
définies dès le début de la fonction qui les contient, du scope ou elle se
trouve, toutes les déclarations du variables sont remonté au début de la
fonction , toutes les déclaration aussi sont remontés au début de la
fonction qui les continents, si ce n’est pas dans un fichier elles seront
remontés au scope globale et on peut les utilisées dans tout le fichier
même on dessus
ou dès le début du fichier si hors de toute fonction
expression function
définies seulement après l’évaluation de l’expression on ne peut pas les
utilisés avant
f1 est une déclaration de fonction et f2
contient une expression de fonction
f1 et f2 sont déclarées dans la fonction f
() , f1 est utilisable car c’est une
déclaration de fonction tandis que f2 est
undifined , on peut appeler f1 mais pas
f2(expression defonction) car undefined
n’est pas une fonction et tant qu’on a
pas évalué ce code f2 n’est pas une
fonction
First class objects :
les fonctions sont de vrais objets Javascript
On peut :
Mettre une fonction dans une variable
Mettre une fonction en propriété d’un objet
Mettre une fonction dans un tableau
Passer une fonction comme paramètre d’une autre
fonction
Renvoyer une fonction
// f est utilisable ici
function f(){ // Declaration
// f1 est utilisable ici
// mais pas f2
function f1(){
// …
}
var f2 = function (){
// …
};
}
function myController($loc , $log){
//...
}
// which services to inject ?
myController.$inject = ['$location' , '$log'] ;
Une fonction peut être passée en
paramètre .Une fonction peut
renvoyer une fonction. Une fonction
c’est un objet donc on peut ajouter
des paramètres
Injection de dépendance
Dans la variable myController on
rajoute une propriété $inject qui est
un tableau avec les nom de ce qu’il
va injecter à la fonction
19. Zaghir Y Javascipt Page 19 sur 40
Exemple de fonction factorisation : calcul de factoriel
Sans cache :
function fonctionFact( n ) {
console.log('calcul:' + n+' value de (n - 1) = '+(n-1)+
' test de (n> 0) ' + (n> 0)) ;
return n> 0 ? n* fonctionFact(n-1) : 1 ;
}
console.log(fonctionFact(5));
Avec Cach :
5 * f(4)
4 * f(3)
3 * f(2)
2 * f(1)
1 * f(0)
1 = 1
= 1
= 2
= 6
= 24
var cache = [] ;
function fonctionFact( n ) {
var cache = [] ;
console.log('calcul:' +n) ;
return n> 0 ? n* fonctionFact(n-1) : 1 ;
}
console.log(fonctionFact(5));
On ne peut pas mettre la
variable ici car elle va être créée
à chaque itération
C’est pas bien de déclarer une varible
global , pour éviter les problèmes de
collisions
20. Zaghir Y Javascipt Page 20 sur 40
'use strict'
function fact(n) {
if(!fact.cache[n]){
console.log('calcul:' +n) ;
fact.cache[n] = n> 0 ? n* fact(n-1) : 1;
}
return fact.cache[n] ;
}
fact.cache = [] ;
console.log(fact(5));
console.log(fact(7));
S’il ne trouve la valeur dans le
tableau il calcule est injecté dans
le tableau
La fonction récursive return fait
appelle à la fonction
Déclaration de la propriété cache
dans l’objet fonction
Les valeurs sont enregistrés dans la
propriété cache de l’objet fonction fact , pas
dans une variable locale
'use strict'
function fact(n) {
if(!fact[n]){
console.log('calcul:' +n) ;
fact[n] = n> 0 ? n* fact(n-1) : 1 ;
}
return fact[n] ;
}
console.log(fact(5));
console.log(fact(7));
On peut utiliser la fonction fact comme un tableau, on peut
passer une propriété n dans l'objet fonction
fact(n) c’est la signature de la méthode
fact[n] tableau de l’objet fonction
21. Zaghir Y Javascipt Page 21 sur 40
Appel de fonction
4 facons d’invoquer une fonction
Appel de fonction classique
Appelée comme une méthode
Appelée comme un constructeur
Avec call ou apply
Paramètres
Pas assez de valeurs : undefined
Trop de valeurs : ignorées, mais accessible dans l’objet arguments
- arguments.length
- arguments[0]
- arguments[1]
- ……
this est égal
à undefined en mode strict
au scope global en mode normal ( !?! )
il faut l’utilisé en mode strict si non la fonction this met tout dans l’objet window . C’est
possible que d’autres fonctions utilisent this et donc problème de collision ou redéfinition
2 ème façon : comme méthode
la fonction est une propriété d’un objet
elle est appelée en faisant référence explicitement à la propriété de l’objet
dans la fonction, this est égal à l’objet qui précède la propriété
Appelé une fonction comme une méthode d’un objet, ce n’est
pas la fonction qui est une méthode d’un objet, c’est seulement
au moment de l’appelle explicite de la fonction sur un objet par
un poids ou par Dans les deux car l’objet dont on récupère la
propriété sa sera la valeur de this
'use strict'
function sum(){
var total = 0 ;
for(var i = 0 ; i < arguments.length ; i++){
total += arguments[i] ;
}
return total ;
}
console.log(sum(1, 2, 3, 4, 5)) ;
arguments c’est un objet spécial
comme this , il n’est pas un
tableau , on ne peut pas utilisé
arguments.reduce de l’objet
Array
la c’est des méthodes qui ne
sont pas appelée sur l’objet
filtered.push(value) ;
fittred : représente le this
filtered.[‘push’](value) ;
'use strict'
var o1 = {
f1 : function(){
return this ;
}
} ;
console.log(o1.f1());
La fonction return un objet avec la fonction f1 , et
l’objet o1 à un prototype de type Object
22. Zaghir Y Javascipt Page 22 sur 40
'use strict'
var o1 = {
f1 : function(){
return this ;
}
};
var o2 = {
f2 :o1.f1
};
console.log(o1.f1());
console.log(o2.f2());
Créer un objet
fonction
Deux références à la
même fonction
La fonction de this
n’est pas
déterminer c’est
lorsque en l’appel
sur un certain objet
que ça va mettre
cette valeur comme
valeur de thisO2.f2 je mets la
même référence
'use strict'
function f(){
return this ;
}
var o1 = {
f1 : f
};
var o2 = {
f2 :o1.f1
};
var f3 = o1.f1 ;
console.log(o1.f1());
console.log(o2.f2());
console.log(f3());
Il faut correspondre
une fonction à un
objet par un poids ou
[]
23. Zaghir Y Javascipt Page 23 sur 40
attention : la valeur de this est perdu dans les fonctions
internes
sauf dans les arrow function de ES6/2015(=>)
pas bon :
'use strict'
controller : function($element , $scope ,
$attrs){
var self = this ;
$scope.$on('$destroy' , function(){
self.renderUnknownOption = noop;
});
},
On copie la valeur de la référence de this , car
this dans une fonction interne ici c’est une
callback est undefined. Donc conserver une
référence au this
On passe une fonction callback qui sert
d’un listener lorsque l’évènement
$destroy' se déclenche
La fonction n’est pas appelé sur un objet
d’où this est undefined , on passe par la
varible self
arrow function , fonction avec une flèche
Fonction n’affecte pas la valeur de this
$scope.$on('destroy' ,
() => {this.renderUnknowOption = noop });
Le this c’est du la
fonction parent() Défini une fonction sans
paramètres this c’est de la
fonction parente
'use strict'
var logger = {
logThis : function(){
console.log(this);
}
};
setTimeout(logger.logThis , 2000) ;
On passe à la fonction setTimeout un référence sur
une fonction.la fonction sera exécuté dans 2s
Le setTimeout va faire l’appelle à une fonction , il ne
connait pas logger , ici il a reçu seulement une
fonction callback () , quand la fonction est appelée
sans objet ou sur un objet la valeur de this est
undefended ou window si on n’est pas en mode
strick
24. Zaghir Y Javascipt Page 24 sur 40
Solution pour esoudre le problème
3 ème facon : comme constructeur
this retourne un objet window
mais pas notre objet logger donc
ce n’est pas bon
'use strict'
var logger = {
logThis : function(){
console.log(this);
}
};
setTimeout(function(){
logger.logThis();
} , 2000) ;
Fonction anonyme
Ne pas passer directement une référence à une
fonction qui devra être appelé sur un certain objet
parce qu’elle ne sera pas, donc définir un fonction
anonyme (quand en passe une fonction en callback
sa sera toujours une fonction anonyme dans laquelle
on appelle notre fonction sur le bon objet )
On récupère les bonnes valeurs de this
var location = new LocationUrl(
convertToHtml5Url(initUrl ,basePath , hashPrefix),
pathprefix,
appbaseUrl
);
25. Zaghir Y Javascipt Page 25 sur 40
mot-clef new
utilisable avec toute fonction JS
convention : le nom de la focntion commence par une majiscule
les constructeurs sa ressemble à des classes mais il n y à pas de classe derniers
Dans javascript on peut utiliser new pour appeler une fonction comme constructeur, mais c’est
toujours une fonction javascript
Pour faire la différence entre les autres fonctions on utilise une majuscule dans le premier caractère
pour dire que c’est un constructeur
JS crée un nouvel objet location
Avec pour prototype LocationUrl.prototype
JS ajoute une propriété prototype à toute fonction
Vérifiant location instanceof LocationUrl
instanceof vérifie si LocationUrl.prototype est dans la chaine des prototypes de
l’objet
Vérifiant location.constuctor === LocationUrl
Parce que la propriété constructor est définie dans son prototype
LocationUrl.prototype
… puis appelle la fonction utilisée comme constructeur
Où this référence le nouvel objet
Avec la new locationUrl ,javascript va créer un nouvel objet qui va dans la variable location et cet
objet va avoir comme prototype l’objet qui est dans la propriété prototype de la fonction qui est
appelé constructeur , quand en créer une fonction javascript pour toute fonction il lui attribue une
propriété prototype qui n’est pas son prototype ou prototype de la fonction, alors une propriété
prototype qui est un objet et cet objet va servira comme prototype à toutes les instances créé on
appellent cette fonction comme constructeur , pour n’importe quelle fonction on a cette propriété
prototype qui était initialisé directement par javascript comme un objet et ce locationUrl.prototype
ça va etre l’objet qui va etre servie à toutes les instances créé on pas new locationUrl dans c’est le
prototype des instances mais pas de la fonction constructeur, chacune des instances va vérifier
location instanceof locationUrl , qui va verifier locationUrl.prototype , le prototype associé au
constructeur et dans la chaine prototype de l’objet crée avec ce constructeur ,et chaque instance va
hériter automatiquement une propriété constructor qui est une référence sur son constructeur parce
que la propriété constructeur est défini dans l’objet locationUrl.prototype donc dans son prototype
ou elle hérite automatiquement de cette propriété .une fois que le new a créé l’objet il lui a affecté le
prototype associe au constructeur il appelle la fonction javascript on lui passant l’objet nouvellement
construit comme valeur de this , tous ce fait sur this dans le constructeur
function LocationUrl(url , pathPrefix , appBaseUrl){
this.parse = function(newAbsoluteUrl){
//.....
};
this.compose = function(){
// ....
};
this.parse(url) ;
}
26. Zaghir Y Javascipt Page 26 sur 40
… et le constructeur ne renvoie rien.
S’il renvoie un type primitif, son retour est ignoré
S’il renvoie un objet, son retour remplace l’objet créé par new
Fortement déconseillé !
En javascript la fonction retourne toujours une valeur si c’est rient elle retourne undefined, en java le
constructeur n’a pas le droit de faire un return il ne compile pas, ne renvoyé pas quelque chose dans
le constructeur car ça va changer la valeur de la variable
Ajout de fonctions au prototype
Fonctions partagées par tous les objets liés à ce prototype
Meme ceux créés avant l’ajout de la fonction au prototype
Quand on utilise un constructeur c’est pour bénéficier du prototype qui est l’objet prototype de la
fonction constructeur et la dedans on peut définir une fonction qui sera hérité pas toutes les
instances créé par ce constructeur
Risque d’oublier le new
Erreur en mode strict, car this vaut undefined
LocationUrl.prototype.f = function(arg1 ,arg2 ){
//....
};
'use strict'
function Person(firstName , lastName){
this.fistName = firstName ;
this.lastName = lastName ;
}
var p1 = new Person("Youssef" , "Souffoun");
Person.prototype.fullName = function(){
return this.fistName + ' ' + this.lastName ;
};
var p2 = new Person("Yassine" , "Dom") ;
console.log(p1.fullName()) ;
console.log(p2.fullName()) ;
Fonction fullName partagé par
toutes les instances créé par le
constructeur Person ,on la déclare
sur le prototype Person this fera
référence de l’instance de la Person,
quand javascript cherche la fonction
fullName elle ne va pas le trouvé elle
le trouve dans le prototype mais elle
l’appelle sur la Person
Sa ressemble à une classe mais c’est qu’on
va juste utiliser une fonction constructeur
d’un objet Person
Toutes les Peron hérite du même prototype quand on ajoute une fonction dans
le prototype, tous les objets habitant cette fonction même après création de
l’objet c’est dynamique, la résolution se fait au moment de la recherche
27. Zaghir Y Javascipt Page 27 sur 40
4 ème façon : call ou apply
Call : appel d’une fonction , en fournissant :
La valeur de this
Les paramètres un à un
call ou apply sont des méthodes de la fonction hérité via le prototype des fonctions qui est
fonction.prototype toutes les fonctions héritent ces deux méthodes call et apply
Exemple : la méthode each() de JQuery
ES6/2015 : class
Une focntion constructeur
Des méthodes sur le prototype associé
static : propriété de la fonction constructeur
fn.call( thisArs , arg1 , arg2 , arg3) ; La valeur de this de cet
fn.apply( thisArs , [arg1 , arg2 , arg3]) ; Un tableau des arguments
Utiliser call si on a des arguments séparé
et apply si on a un tableau des arguments
N’importe quelle focntion peut etre appelé
sur n’importe quoi
// Utilisation : this est l'élément HTML courant
JQuery('a').each(function(index , value){
var ihref = $(this).attr('href');
if(ihref.indexOf("http") >= 0){
console.log(ihref+'<br/>');
}
});
// dans le code du each du JQuery
for( ; i <length ; i++){
value = callback.call(obj[i] , i , obj[i]) ;
}
La méthode callback fait
appelle à la méthode call
Pas besoin d’avoir un objet
pour faire appel à la fonction
Une Classe c’est :
une fonction constructeur
avec un prototype associé
28. Zaghir Y Javascipt Page 28 sur 40
extends peu utile en JS !
class Point {
constructor(x, y){
this.x = x ;
this.y = y ;
}
toString(){
return '('+ this.x + ' , '+ this.y +')' ;
}
}
Point resemble à une classe, en
fait c’est une fonction
constructeur
toString c’est la redéfinition de la
méthode toString de l’objet ,
redéfini pour quelle être appelé
par toutes les instances de Point
c’est exactement
Point.prototype.toString dans ES5
class Rectangle {
constructor(witdth , height){
this.width = width ;
this.height = height ;
}
static area(width , height){
return width * height;
}
area(){
return Rectangle.area(this.width , this.height) ;
}
}
Méthode static va créer une
fonction comme une
propriété dans la fonction
constructeur
class ColorPoint extends Point {
constructor(x , y , color){
super(x , y) ;
this.color = color ;
}
toString(){
return super.toString() + ' in ' + this.color ;
}
}
Il n y a pas de classe dans JS,
l’héritage et différent de
celui de JAVA
29. Zaghir Y Javascipt Page 29 sur 40
Equivalent à (ES5)
Closure
Toute fonction Javascript a accés aux données du scope dans lequel elle à été définie.
self est accessible dans la fonction interne car c’est une variable du scope dans lequel la
fonction interne est definie
Fonctionnement
La fonction garde une référence vers son scope de définition (variables, paramètres et
fonctions)
Les données sont celles présentes dans le scope au moment de l’exécution de la fonction
- Pas au moment de sa définition (pas de copie d’état du scope)
- c’est une référence pas une copie :au moment où la fonction interne est exécuté elle
verra les valeurs en cours ,il n y a pas de copie ou le moment la fonction est créée
-
Conséquences :
Une fonction globale à accès aux données de scope global
Une fonction interne a accès aux données de son scope de définition
- = celle de la fonction dans laquelle elle est définie
- … qui a elle-même accès aux données de son scope de définition
- … et ce jusqu’au scope global
function ColorPoint(x , y , color){
Point.call (this , x , y) ;
this.color = color ;
}
ColorPoint.prototype = new Point() ;
ColorPoint.prototype.constructor = ColorPoint ;
ColorPoint.prototype.toString = function(){
return Point.prototype.toString.call(this)
+' in '+this.color ;
};
Définir une fonction constructeur avec 3 paramètres
Point on l’appelle sur this et on lui passant ces
paramètres x , y
toString Parent en va le cherché dans le toString
associé au parent Point.prototype.toString.call sur this
ColorPoint.prototype à un prototype , c’est
l’instance de l’objet Point , il faut créer l obj
controller: function($element , $scope , $attrs){
var self = this ;
$scope.$on('$destroy' , function(){
self.renderUnknownOption = noop ;
}) ;
}
En javascript n’import quelle fonction
peut accederà toutes les données dans le
scope ou elle est défini , self peut acceder
à n’inport quelle donnée
function /
scope
Scope parent
Scope globale
30. Zaghir Y Javascipt Page 30 sur 40
Attention aux memory leaks !
JS purge le scope à la sortie de la fonction parente
- conserve les propriétés appelées
- y compris les closures qui ne sont plus référencées !
Solution : annuler les propriétés ne devant pas être conservées
Les interpréteurs javascript vont purger du scope parent tous ce qui est
utilisé dans les fonctions internes, quelque chose qui n’est pas
référencée dans une closure elle ne sera référencée
Un bon exemple la closure dans les boucles
'use strict';
var v0 = 0 ;
function f1(arg1){
var v1 = 1 ;
return function f2(arg2){
var v2 = 2 ;
return function f3(arg3){
var v3 = 3 ;
console.log(v0 , v1 , v2 , v3) ;
console.log(arg1 , arg2 , arg3 );
}
}
}
f1('aaa')('bbb')('ccc') ;
La fonction f1 se termine et dans son
return elle fait appelle à la fonction f2
f1 et f2 sont terminées et on a encore
une référence sur le scope de la
fonction f2 et encore une référence
sur le scope parent f1 et on peut
récupérer la valeur de v1
et encore on a le scope globale de
toute l’application
f1 est
exécuté
f2 est
exécuté
f3 est
exécuté
'use strict'
controller : function($element , $scope ,
$attrs){
var self = this ;
$scope.$on('$destroy' , function(){
self.renderUnknownOption = noop;
});
} ;
La variable self va être conserver et
utiliser dans la fonction interne
Les interpreteur ne sont pas aussi
puissants car ils vont garder tous
donnée fonction tableaux ou
variable qui sont dans une fonction
interne n un scope qui ne peut pas
libéré la mémoire
'use strinct'
function count(){
for(var i = 1 ; i <= 10 ; i++){
setTimeout(function(){
console.log(i);
} , i * 1000) ;
}
}
count() ;
fonction callback donc asynchrone
c’est une fonction interne elle a
gardé une référence vers le scope
parent dans lequel elle trouve la
valeur de i, à la fine de la boucle i
= 11 est toutes les fonctions
callback vont trouver la valeur de i
= 11 , i c’est une référence dans le
scope parent
i= 11
la fonction count () à 1 seul scope
31. Zaghir Y Javascipt Page 31 sur 40
Pour résoudre le problème
Résoudre le problème par une fonction anonyme ou anonymous
wrapper appelé immédiatement
'use strinct'
function log(i){
setTimeout(function(){
console.log(i);
} , i * 1000) ;
}
function count(){
for(var i = 1 ; i <= 10 ; i++){
log(i);
}
}
count() ;
Pour conserver 10 valeur de 1
différentes il faut créer 10 scope
parent différents
ce qui crée un scope c'est l'appelle
de la fonction
I est une variable primitive ca créé une
copie de la valeur de i , si c’était un objet
il faut le cloné
10 Appelle à la fonction, donc
création de 10 nouveau scope
avec des nouvelles valeurs de i
function count(){
for(var i = 1 ; i <= 10 ; i++){
function (i){
setTimeout(function(){
console.log(i);
} , i * 1000) ;
}(i) ;
}
}
count() ;
- On a pas le droit de créer un
fonction dans une boucle for le
mode strict l’interdit
- Les déclarations de fonction
n’ont pas de valeurs ( ca
commence par function)
- pour avoir une expression et
pouvoir l’appelé in ne faut pas
être au début d’instruction
32. Zaghir Y Javascipt Page 32 sur 40
Anonymous wrapper
Fonction anonyme exécutée immédiatement
- Entre parenthèse, pour que ce soit une expression
- Avec ou sans arguments
Fonction anonyme exécutée immédiatement
- Alternative avec moins de parenthèses
Usage : créer un scope contenant les variables et les fonctions
- Ne pas polluer le scope global
- Encapsuler le contenu de chaque fichier dans un anounymous wrapper
function count(){
for(var i = 1 ; i <= 10 ; i++){
( function (i){
setTimeout(function(){
console.log(i);
} , i * 1000) ;
} ) (i) ;
}
}
count() ;
On enveloppe la fonction dans deux
parenthèses
La fonction entre deux parenthèses
pour dire que c’est une expression qui
renvoie une valeur si non c’est un
instruction elle ne renvoie pas de
valeurs
Il faut toujours utilisé une fonction
anonyme dans le cas d’utilisation des
fonctions callback
(function (arg1, arg2) {
// ...
}) (a1, a2 ) ;
!function (arg1, arg2) {
// ...
} (a1, a2 );
!function renvoie false est false de
l’objet c’est une valeur
Le principe c’est d’avoir quelque chose
devant la fonction
(function () {
// ...
}) () ;
L’appel de la fonction ()
Scope interne dans la fonction, separer du
scope globale
Bonne pratique c’est de déclarer nos
traitement dans une fonction anonyme ()
pour éviter les collisions …
33. Zaghir Y Javascipt Page 33 sur 40
Pattern "Module"
factory anonyme :qui sert à créer l’objet appelée immédiatement
- variables locales = données et fonction privées du module
- renvoie un objet
avec des propriétés et méthodes publiques
qui ont accès aux données et fonction privées
un module en javascript : simuler de méthode privées ou propriétés privées
dans un objet
Example:
var module = (function(){
var privatevariable = 1 ;
var privateMethod = function(){
// ....
} ;
return {
moduleProperty : 1 ,
moduleMethod : function(){
//....
privateVariable = 2 ;
privateMethod();
}
};
}());
L’objet retourné par la factory
Appelé la factory immédiatement
ici sans passé des paramètres
Accès à toutes les variables locale
de la factory
Notre
module
sera
'use strinct'
//Module (= anonymous factory )
var c = (function(){
var value = 0 ;
return{
get:function(){
return value ;
},
inc:function(i){
value += i || 1 ;
}
};
}());
console.log(c.get());
c.inc();
console.log(c.get());
c.inc(4);
console.log(c.get());
Variable de la factory
Astuce soit en i += 1 soit i += v
34. Zaghir Y Javascipt Page 34 sur 40
'use strinct'
//factory
function counterFactory(init){
var value = init ;
return{
get:function(){
return value ;
},
inc:function(i){
value += i || 1 ;
}
};
};
var c1 = counterFactory(10) ,
c2 = counterFactory(20) ;
console.log(c1.get() , c2.get()); c1.inc();
console.log(c1.get() , c2.get()); c2.inc(4);
console.log(c1.get() , c2.get());
Chaque appel à la fonction crée
un nouveau scope propre à la
fonction , propre value
'use strinct'
//Constructor
function Counter(init){
var value = init ;
this.get = function(){
return value ;
};
this.inc = function (i){
value += i || 1 ;
};
};
var c1 = new Counter(10) ,
c2 = new Counter(20) ;
console.log(c1.get() , c2.get()); c1.inc();
console.log(c1.get() , c2.get()); c2.inc(4);
console.log(c1.get() , c2.get());
Fonction Constructeur, premier
caractère par convention
On a pas profité de prototype
pour créer les méthodes get et
inc , si on les défini dans le
prototype , get et inc ne vont
accéder à value
35. Zaghir Y Javascipt Page 35 sur 40
Operateurs && et ||
&& et || ne renvoient pas forcément un booléen
Renvoient la valeur du denier opérande évalué
- Avec court-circuit de l’évaluation
val1 && val2
- si val1 est équivalent à true , renvoie val2, si non val1
- accéder à une propriété seulement si l’objet est défini
'use strinct'
//Constructor + prototype
function Counter(init){
this._value = init ;
}
Counter.prototype.get =function(){
return this._value ;
};
Counter.prototype.inc = function(i){
this._value +=i || i ;
};
var c1 = new Counter(10) ,
c2 = new Counter(20) ;
console.log(c1.get() , c2.get()); c1.inc();
console.log(c1.get() , c2.get()); c2.inc(4);
console.log(c1.get() , c2.get());
Si on veut partager la méthode
get et inc , on les défini dans le
prototype mais il faut définir la
propriété value dans le
prototype ,
La propriété ne sera plus
variable local car elle est dans
le prototype un scope parent
partage
obj && obj.fb()
args.push(
locals && locals.hasOwnProperty(kye)
? locals[key]
: getService(key)
);
Il va convertir / caster en
booléen val1 si égal à true il va
évaluer le 2eme opérant sis le
est vérifié
False = prend comme valeur
false , null , chaine vide , 0 ,
undefined ,NaN(not a number)
Et true c’est l’inverse
Accéder à une propriété si
seulement si un objet est défini
si l’objet est undefined alors il
envoie false, sa envoie la
première valeur qui égale à
false et il n’évalue pas la suite,
donc pas d’exception
Si l’objet est défini il envoie la
fonction
36. Zaghir Y Javascipt Page 36 sur 40
Opérateur ||
val1 || val2
- si val1 est équivalent à true, renvoie val1 , sinon val2
- valeur par défaut
Boucles for et for…in
for…in :
- pour itérer sur les noms des propriétés (énumérables) d’un
objet
Elle sert à itéré les propriétés de l’objet, uniquement les propriétés qui sont énumérables.
On itère sur les noms des propriétés de l’objet pas sur les valeurs, et pour chercher les valeurs il
faut utiliser les crochés []
problème : itère aussi sur les propriétés héritées , car si une personne ajoute une propriété
dans le prototype après ,cette boucle ne marche plus
arg1 || { }
match = {
protocol: match[1],
host : match[3] ,
port : int(match[5]) || DEFAULT_PORTS[match[1]] || null ,
path : match[6] || '/'
};
Ou logique très utilisé dans JS,
pour indiquer la valeur par
défaut , si on a un argument
undefined , il va envoyer un
objet videSi on a pas numero de port sa va
prendre DEFAULT_PORTS ou
alors encore null
value += i || 1 ; Si la valeur de i est null il utilise 1 comme valeur si non i
// Bad
for(var prorepertyname in obj){
var propertyValue = obj[propertyName];
// ....
}
37. Zaghir Y Javascipt Page 37 sur 40
ignorer les propriétés héritées du prototype :
lister les propriétés locales(non héritées) d’un objet
- Object.keys(obj) (ES5) :
Tableau des noms des propriétés énumérables de l’objet
Quand on crée une propriété avec la syntaxe poids ou croché elle est énumérable si
non c’est elle n’est pas énumérable
- Objet.getOwnPropertyName(obj) (ES5) :
Tableau des noms de toutes les propriétés de l’objet, énumérable ou non
Ne jamais utiliser for … in pour itérer sur les éléments d’un
tableau
- Aucune garantie sur l’ordre
- Les éléments valant undefined sont sautés
- Ça itère aussi sur les autres propriétés (non numériques) éventuellement ajoutées au
tableau
C’est possible d’itérer sur les éléments de l’objet lui-même
Les index non défini ne seront pas renvoyés [0, 1, 2, undefined,..]
Boucle for numérique pour itérer sur les éléments d’un tableau
… ou utiliser la méthode forEach() des tableaux.
Exceptions :
try … catch
// Good
for(var propertyName in obj){
if(obj.hasOwnProperty(propertyName)){
var propertyValue = obj[propertyName] ;
// ...
}
}
Pour ignorer la propriété il faut
tester l’objet par la fonction
propre à javascript
obj.hasOwnProperty, elle est
hérité de Object.prototype
Tester si c’est une propriété a
l’obj ou une propriété hérité
for(var i = 0 ; i < arr.length ; i++){
var element = arr[i] ;
//....
}
try {
// ....
} catch(e) {
// ....
}
Rien n’est typé dans javascript ,
pas de variable type donc un
seul bloc pour gérer ou
récupérer toutes les exceptions
e récupéré l’exception , rien
n’interdit de faire des if dans le
catch pour traiter e
38. Zaghir Y Javascipt Page 38 sur 40
Un seul catch pour tout type d’exception
try … catch … finally
déclencher une exception : throw avec une valeur quelconque
- ex : message d’erreur (string)
- ex : objet avec une méthode toString ()
utilisée pour le message affiché dans ma stack trace
try{
// ....
} catch(e){
// ....
} finally{
//....
}
throw new Error(message) ;
) ;
throw "Error3" ; La valeur de e = "Error3"
'use strict'
function ZipCode(zip){
if(/[0-9]{5}([- ]?[0-9]{4})?/.test(zip)){
// ...
} else {
throw new ZipCodeFormatException(zip) ;
}
}
function ZipCodeFormatException(value){
this.value = value ;
this.message = "is not a valid zip code" ;
this.toString = function(){
return this.value + this.message ;
};
}
var test = ZipCode('xxx');
Dans le constructeur
ZipCodeFormatException on
stock la valeur erroné
Dans une exception c’est
important de redéfinir la
méthode toString() car c’es
elle qui sera utilisé dans la
stack trace
La méthode toString par
défaut de l’objet c’est object
object ce n’est pas très
explicite
39. Zaghir Y Javascipt Page 39 sur 40
JS patterns
Duck typing codage du canard
"if it walks like a duck and quacks like duck, it’s a duck."
Exemple
Note: the slice function is intentionally generic; it does not require that it’s this value be an
Array object .
Therefor it can be transferred to other kinds of objects for use as a method.
Typage par l’usage, contrat implicite
Sans typage statique, pas besoin :
- De classes
- D’interfaces
- D’héritage
Le prototypage n’est qu’un moyen de partager du code
Il ne faut le voir comme un héritage comme dans java , on a pas la notion de contrat ou
interface dans javascript , on créé et on test si ça marche
function logValue(it){
var next = it.next();
console.log(next) ;
}
function sum(){
var args = Array.prototype.slice.call(arguments) ;
return args.reduce(function(sum , item){
return sum + item ;
}, 0);
}
console.log(sum(1 , 2 , 3 ) ;
function sum(){
return Array.prototype.reduce.call(arguments,
function(sum , item){
return sum + item ;
}, 0);
}
console.log(sum(1 , 2 , 3 ) ;
40. Zaghir Y Javascipt Page 40 sur 40
Mixing Extend
Au lieu de faire un héritage on va ajouter à l’objet ce qu’il a besoin
L’héritage c’est de prendre un objet et d’ajouter d’autre fonctions
dans le prototype
Configuration object
Au lieu de passer plusieurs arguments, vaut mieux utiliser un objet (Objet de configuration) bon
pratique
Promesses
Utiliser les promesses pour gérer l’asynchronisme.
Disponibles dans de nombreux Framework, et en ES6/2015
Promesse :
- Objet qui représente un résultat asynchrone
- Ne contient jamais le résultat
- Méthode then pour enregistrer :
o Un callback de succès
o Un callback d’erreur
- On appelle then () que la promesse soit en attente ou déjà
résolue
function sum(){
angular.extend(arguments , {
map : Array.prototype.map,
reduce: Array.prototype.reduce
});
return arguments.reduce(function(sum , item){
return sum + item ;
}, 0 );
}
$http({
method :'GET',
url :'https://angularjs.org/',
cache: true ,
withCredentials :true
});
// Beaucoup mieux que
http('GET' , 'https://angularjs.org/' , undefined ,
undefined ,undefined , true , undefined , true);
C’est possible d’ajouter des
paramètres à la méthode (objet)
sans changé son comportement
#
A la deuxième méthode