Javascript : fondamentaux et OOP
-
Upload
jean-pierre-vincent -
Category
Technology
-
view
4.646 -
download
1
description
Transcript of Javascript : fondamentaux et OOP
Javascript
Les fondamentauxLa POO
Jean-pierre VINCENT
Qui ça ?Jean-pierre VINCENT
braincracking.org (veille techno)@theystolemynick
10 ans de WebConsultant, formateur, expertise
Pourquoi Javascript ?
Présent partout● Navigateur● Jeux Web (remplace Flash)● Mobile (Phonegap ...)● Télévisions● Serveur (Node.js, ...)● Software (Chromeless, ...)● OS (JoliCloud, WebOS...)● Windows 8 !
Mauvaise réputation
Mauvaise réputation
parseInt('06'); // 6parseInt('08'); // 0
wftjs.com
Mauvaise réputation
typeof NaN // numberNaN === NaN // false
typeof null // objectnull instanceof Object // false
wftjs.com
Mauvaise réputation
(1.7976931348623157e+308 === 1.7976931348623158e+308 )// true!
alert(111111111111111111111); // alerts 111111111111111110000
9999999999999999 //=> 10000000000000000
wftjs.com
APIs● DOM
● Node
● WinRT
●...
Compliqué ?
Différent !
Historique court● Né pendant la guerre (95)● En quelques semaines● Influence Java, Erlang, Lisp, Python
IE et Netscape d'accord pourEcmaScript 3
Evolution
● EcmaScript 5● Harmony● EcmaScript.Next ● EcmaScript.Next.Next
En attendant ...
EcmaScript 3
Objectif de cette heure
● Savoir deboguer avec 3 fondamentaux
● Développer Orienté Objet
Notions de base
● Portée des variables (var + function)
● Function()
● Contexte (this)
Portée des variables
1 closure = 1 portée
Closure = function() {PORTÉE
}
Portée des variablestest1 = function() { var x = 1; test2 = function() { var x = 2; test3 = function() { var x = 3;
console.log(x); // 3 }(); }(); console.log(x); // 1}();console.log(x); // undefined
Boucle infinie !function genericFunctionName() { for(i = 0; i < myArray.length; i++) { .... }}
for(i = 0; i < 10; i++) { genericFunctionName();}
Boucle corrigéefunction genericFunctionName() { for( var i = 0; i<myArray.length;i++){ .... }}
for(i = 0; i < 10; i++) { genericFunctionName();}
Application pratique(function() {
var privateVariable = true;function init() {
console.log( privateVariable );}
}())
init(); // trueconsole.log(privateVariable);//undefined
Créer un scope1
function() { var privateVariable = true; console.log( privateVariable ); } => parse error
Créer un scope2
( function() { var privateVariable = true; console.log( privateVariable ); }) => rien
Créer un scope3
( function() { var privateVariable = true; console.log( privateVariable ); })() => true
Notions de base
✓ Portée des variables (var + function)
● Function()
● Contexte (this)
Function()
● function action() {}
● action = function() {}
● action();
function action()
Toujours globale action(); // true..function action() { console.log(true);}
function action()TROP globaleaction(); // a !== 1if( a === 1) { function action() { console.log('a === 1'); }} else { function action() { console.log('a !== 1'); }}
var action = function()
Permet de choisir la portée
Peut s'auto-exécuter
autoInit = function() {console.log('hello world');
}();// hello world
return function()var onDOMEvent = function( el, ev, callback) { if(document.body.attachEvent){
el.attachEvent('on'+ev, callback); } else {
el.addEventListener( ev, callback);}
};
return function()var onDOMEvent = function( el, ev, callback) { if(document.body.attachEvent return function(el, ev, callback) { element.attachEvent('on'+event, callback); }; else return function(el, ev, callback) {
el.addEventListener( ev, callback); };}();
Function.prototypevar myClass = function () { this.publicVariable = 0;};
myClass.prototype = { decrement:function() { console.log( --this.publicVariable ); }, increment:function() { console.log( ++this.publicVariable ); }};
Function.prototypevar myClass = function () {};myClass.prototype = { decrement:function() {}, increment:function() {}};myObject = new myClass();myObject.decrement(); // -1myObject.decrement(); // -2myObject2 = new myClass();myObject2.increment(); // 1myObject2.increment(); // 2
Héritage
mySubClass = function() {this.publicVariable = 10;
};mySubClass.prototype = myClass.prototype;mySubClass.prototype.constructor = mySubClass;
myObject2 = new mySubClass();myObject2.increment(); // 11myObject2.increment(); // 12
Renvoi d'objetsmyClass = function () { var privateVariable = 0; // public methods return { decrement:function() { console.log( --privateVariable ); }, increment:function() { console.log( ++privateVariable ); } }};
Renvoi d'objetsmyClass = function () { return { decrement:function() { }, increment:function() { } }};myObject = myClass();myObject.decrement(); // -1myObject.decrement(); // -2myObject2 = myClass();myObject2.increment(); // 1myObject2.increment(); // 2
Function === ObjectmyClass = function () { return { publicMethod:function() {} } };myClass.staticMethod = function() {};
myObject = myClass();myObject.staticMethod(); // Error
myClass.publicMethod(); // Error
Portée + déclarationvar queries = [ new XHR('url1'), new XHR('url2'), new XHR('url3')];
for(var i = 0; i < queries.length; i++) { queries[i].onload = function() { console.log( i ); // référence };}
queries[ 0 ].onload(); // 3!queries[ 1 ].onload(); // 3!queries[ 2 ].onload(); // 3!
Portée + déclaration
for(var i = 0; i < queries.length; i++) { queries[i].onload = function(i) { return function() { console.log( i ); // valeur }; }(i); // exécution immédiate}// plus tard ...queries[ 0 ].onload(); // 0queries[ 1 ].onload(); // 1queries[ 2 ].onload(); // 2
Notions de base
✓ Portée des variables (var + function)
✓ Function()
● Contexte (this)
Contexte
this = contexte d'exécution
Contexte - facile
myClass = function() {this.id = 'myClass';
}myClass.prototype = {
action:function() {console.log(this.id);
}};
myObject = new myClass();myObject.action(); // 'myclass'
Contexte - DOMmyClass = function() {
this.id = 'myClass';}myClass.prototype = {
action:function() {console.log(this.id);}
};myObject = new myClass();document.body.onclick = myObject.action;
// document.body.id
Contexte – tous objetsmyClass = function() {
this.id = 'myClass';}myClass.prototype = {
action:function() {console.log(this.id);}
};myObject = new myClass();myEvent = {
id:'myObj2'}myEvent.onfire = myObj.action;myEvent.onfire(); // myObj2
Contexte – fix natifmyClass = function() {
this.id = 'myClass';}myClass.prototype = {
action:function() {console.log(this.id);}
};myObject = new myClass();myEvent = {
id:'myObj2'}myEvent.onfire = myObj.action;myEvent.onfire.call( myObject ); // myClass
Contexte: sans prototypemyClass = function() { this.id = 'myClass'; var me = this; return { action:function() { console.log(me.id); } }};myObject = myClass();document.body.onclick = myObject.action;// 'myClass'
Notions de base
✓ Portée des variables (var + function)
✓ Function()
✓ Contexte (this)
Développement durable
● Pollution du scope global
● Programmation Orienté Objet
Pollution globale
Pollution globale2 exemples complètement au hasard
● Gmail : 33 variables globales (450K lignes de code)
● Lemonde.fr : 480 variables globales
Actions
✗ Function action() {}
✓ var action = function() { var myVariable; }
✓namespaces
Namespaces
var MY_APP_NAMESPACE = {};
MY.doSomething = function() {};
MY.utils = {};
MY.utils.XHR = function() {
}
Namespaces - astuce
récupérer ou créer un namespace
MY = windows.MY || {};
MY.utils = MY.utils || {};
Création d'un scopeRappel
(function(){ // début de scope local var private = true;
// ici je suis chez moi
})(); // fin de scope local
ProgrammationOrientéObjet
Tout est objet
"abc".indexOf('a');
[1,2,3].slice(1);
13.3714 .toFixed(1);
/[0-9]/g.test('10/11/2011');
POO Classique
new, class, static, public, private, __construct, $this, const, self::, extends, protected, parent::, abstract, final, interface, implements, instanceof
POO JS
new (optionel) this (particulier) instanceof
Interface publique(function(){ // début de scope local
// accès global au constructeur MY.utils.XHR = function( url ) { this.url = url; }; // méthodes ou variable statiques MY.utils.XHR.staticVariable = true;
})(); // fin de scope local
Raccourci(function(){ // début de scope local
// raccourci vers le namespace utilisé var self = MY.utils.XHR; self.staticVariable = true;
})(); // fin de scope local
privées communes(function(){ // début de scope local
// accès global au constructeurMY.utils.XHR = function( url ) { this.url = url; currentInstances.push( this );};var currentInstances = [];
})(); // fin de scope local
privées par instance(function(){ // début de scope local// accès global au constructeurMY.utils.XHR = function( url ) { var isConnecting = true; return { query:function() { if( isConnecting) return false; } }};})(); // fin de scope local
Combo : factory pattern(function(){MY.utils.XHR = function( ) { throw new Error( 'please use .getInstance()' );};// constructeur privévar XHR = function(url) { console.log(url); };// liste privéevar currentInstances = {};// factoryMY.utils.XHR.getInstance = function( url ) { if(currentInstances[url]) return currentInstances[url]; else return currentInstances[url] = new XHR( url);}})();
Tout est émulable
● programmation événementielle
● tests unitaires et fonctionnels
● patterns classiques : MVC, observer, facade, proxy, singleton, factory ...
Conclusion
● Javascript est différent, apprenez le
● OOP réutilisable
Questions ?
Jean-pierre VINCENTbraincracking.org@theystolemynick