Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript
JavaScript Forum programmation JavaScript. Lire : Cours JavaScript, FAQ JavaScript, Toutes les FAQ JavaScript et Sources JavaScript
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 09/12/2011, 14h48   #1
Invité régulier
 
Inscription : octobre 2005
Messages : 22
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 22
Points : 6
Points : 6
Par défaut OOP et javascript : proto ou pas proto ?

Bonjour, après des années passées à utiliser les frameworks existants j'essai de revenir à l'essentiel pour une meilleure compréhension.

En premier lieu je cherche à transposer mes connaissances de l'OO vers javascript à l'aide d'un bouquin (jS, gardez le meilleur de Douglas Crockford).

Bon, bref. J'ai bien compris qu'il n'y a pas de notion de classe en JS et que tout est objet. Je vois aussi à quoi sert le prototype.

Par contre, j'ai fait un petit test et il y a un truc qui m'échappe.

Quelle est la différence entre les méthodes dosomething et sogood ??
A l’exécution j'obtiens exactement le même comportement (attendu). Dans ce cas, pourquoi devrais-je utiliser une déclaration par prototype ?

Merci d'avance


Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
var Player = function (name) {
    this.name = name;
    this.dosomething = function(arg) {
        console.log(this.name + ' here with ' + arg);
    }
}
 
Player.prototype.sogood = function(arg) {
    console.log(this.name + ' here proto with ' + arg);
}
 
var p1 = new Player('bodo');
p1.dosomething('toto');
p1.sogood('toto');
Ah puis, tant qu'on y est - quelle est la différence entre

Code :
1
2
var Player = function (name) {
}
et

Code :
1
2
var Player = function Player(name) {
}
Paganoni est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 14h57   #2
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 872
Points : 1 381
Points : 1 381
Pour ta première question, il existera toujours UNE et UNE seule instance de la fonction "sogood".

Tandis que la fonction dosomething ne sera déclaré que lorsqu'un objet sera instancié et sera propre à cet objet, c'est à dire qu'il existera une fonction "dosomething" pour chaque objet instancié.

Code :
1
2
3
4
5
6
7
8
9
ex:
var p1 = new Player('bodo1');
var p2 = new Player('bodo2');
if( p1.dosomething == p2.dosomething ){
 // FALSE
}
if( p1.sogood == p2.sogood ){ 
 // TRUE
}
ne pas dupliquer une fonction (avec les prototypes) permet notament d'épargner pas mal de placer et d'exécution lors que tu crées des quantités conséquentes d'objets.

tu peux tester si une fonction (ou attribut) est propre à un objet grace à la méthode "hasOwnProperty"

Code :
p1.hasOwnProperty('sogood'); // false
l'avantage de redéclarer une méthode à l'intérieur de l'objet peut par exemple être utile pour accèder à des champs privés comme les getters.

Code :
1
2
3
4
5
6
7
8
9
function Player(name){
    var _name = name;
    this.getName = function(){
        return _name;
    };
}
Player.prototype.getNameProto = function(){
    return _name; // ne fonctionnera pas
};
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 14h58   #3
Responsable Développement Web

 
Avatar de Bovino
 
Homme Didier Mouronval
Développeur Web
Inscription : juin 2008
Messages : 13 808
Détails du profil
Informations personnelles :
Nom : Homme Didier Mouronval
Âge : 41
Localisation : France, Gironde (Aquitaine)

Informations professionnelles :
Activité : Développeur Web
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : juin 2008
Messages : 13 808
Points : 35 789
Points : 35 789
Citation:
Dans ce cas, pourquoi devrais-je utiliser une déclaration par prototype ?
Tout simplement pour des questions entre autre de performances.
Lorsque tu déclares la méthode dans le constructeur, chaque instance de l'objet que tu vas créer va définir sa propre méthode, alors que si tu la déclares dans le prototype, chaque instance héritera de la même définition.
__________________
Pas de question technique par MP !
Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
Vous possédez un blog et aimeriez diffuser vos billets sur le forum, contactez-moi !
Mes formations video2brain : La formation complète sur JavaScriptJavaScript et le DOM par la pratiquePHP 5 et MySQL : les fondamentaux
Mon livre sur jQuery
Bovino est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 15h12   #4
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 872
Points : 1 381
Points : 1 381
Citation:
Envoyé par Paganoni Voir le message
Ah puis, tant qu'on y est - quelle est la différence entre

Code :
1
2
var Player = function (name) {
}
et

Code :
1
2
var Player = function Player(name) {
}
le 2ème exemple n'existe pas vraiment (sauf erreur de codeur) car ça revient au même que de faire :

Code :
function Player(name){}
maintenant la différence entre :

Code :
1
2
3
function Player(){}
et 
Player = function(){};
est que dans le 2ème cas il s'agissent d'une fonction anonyme assigné à la variable "Player". (enfin au pointeur, vu que tout les objets et fonctions se joue avec des pointeurs en javascript.)

dans le premier cas, il s'agit d'une fonction nommée qui se également pointé par la variable "Player".

en gros, les 2 façons de faire se valent et son (quasi) équivalentes. les deux sont en général autant utilisés. même si la function nommée permet (sous chrome et firefox mais pas IE) de renvoyer le nom de la fonction via l'attribut "name". ex :

Code :
1
2
3
4
5
6
7
function b(){};
var maFonction = b;
alert(maFonction.name); // b
 
var b = function(){};
var maFonction = b;
alert(maFonction.name); // ... null ou undefined (je sais plus ^^)
en bref, ça dépendra surtout de tes habitudes si tu préfères d'avoir voir "function" ou le nom de la fonction.

aussi si tu as l'habitude de coder dans des objets, tu auras plus tendances à utiliser l'assignation je pense, par habitude. ex :

Code :
1
2
3
4
5
6
var obj = {
  alpha : function(){},
  beta : function(){},
  num : 5,
  text : "blabla"
};
enfin, dernière anecdote, le point-virgule n'est pas nécessaire à la fin de la déclaration d'une fonction tandis qu'il est obligatoire après une assignation. il est donc souvent oublié quand on débute en javascript et est source d'erreur. ex :

Code :
function alpha(){}/*pas besoin de ; ici*/alpha();

Code :
var alpha = function(){};/*besoin du ; ici pour clore l'assignation*/alpha();
voila, cet énorme texte pour dire que les 2 reviennent exactement au même.
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 09/12/2011, 18h14   #5
Invité régulier
 
Inscription : octobre 2005
Messages : 22
Détails du profil
Informations forums :
Inscription : octobre 2005
Messages : 22
Points : 6
Points : 6
Rha bin c'est bien sûr !

Merci beaucoup pour vos éclaircissements !
Paganoni est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 21h28   #6
Membre Expert
 
Avatar de Watilin
 
Homme Matilin Torre
Étudiant
Inscription : juin 2010
Messages : 679
Détails du profil
Informations personnelles :
Nom : Homme Matilin Torre
Âge : 23
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juin 2010
Messages : 679
Points : 1 202
Points : 1 202
Citation:
Envoyé par Willpower Voir le message
le 2ème exemple n'existe pas vraiment (sauf erreur de codeur)
Si si, ça existe, et non non ce n'est pas une erreur C'est même très utile car le nom de la fonction apparaît dans la pile d'appel quand on fait du debug.

Un exemple tout simple :
Code HTML :
1
2
<input type="button" id="bouton1" value="1" />
<input type="button" id="bouton2" value="2" />
Code :
1
2
3
4
5
6
7
8
9
10
document.getElementById('bouton1').addEventListener(
	'click', function() { // fonction anonyme
		var x;
		x.flute = 'oups';
	}, false);
document.getElementById('bouton2').addEventListener(
	'click', function Hareng() { // fonction nommée
		var x;
		x.reponse = 42;
	}, false);
Avec Firebug, j'obtiens ceci quand je clique sur « 1 » :
Code :
1
2
3
x is undefined
(?)()
x.flute = 'oups';
et ceci quand je clique sur « 2 » :
Code :
1
2
3
x is undefined
Hareng()
x.reponse = 42;
__________________
Disposition de clavier ergonomique française : Bépo
Watilin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/12/2011, 21h51   #7
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 872
Points : 1 381
Points : 1 381
en fait, je parlais de nommer la fonction et de réassigner la fonction dans elle-même :

Code :
var NOM = function NOM(){};
qui n'avait aucun sens et qui revenait à faire tout simplement :

Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/12/2011, 17h13   #8
Membre Expert
 
Avatar de Watilin
 
Homme Matilin Torre
Étudiant
Inscription : juin 2010
Messages : 679
Détails du profil
Informations personnelles :
Nom : Homme Matilin Torre
Âge : 23
Localisation : France, Ille et Vilaine (Bretagne)

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juin 2010
Messages : 679
Points : 1 202
Points : 1 202
Ah oui, là je suis d'accord, ça revient exactement au même
__________________
Disposition de clavier ergonomique française : Bépo
Watilin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/12/2011, 12h31   #9
Membre régulier
 
Inscription : décembre 2007
Messages : 61
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 61
Points : 83
Points : 83
Non ça ne revient pas vraiment au même.

L'une est une expression et l'autre est une déclaration, ce qui veut dire que les deux ne sont pas évaluées au même moment.

La déclaration sera évaluée (elle ainsi que les autres déclarations qu'elle contient) à l'entrée du contexte), l'expression sera évaluée à l'execution.

Cela peut avoir son importance en cas d'évaluation tardive (lazy init) ou de branchement de code. Si les invariantes à initialiser sont couteuse, très rarement utilisées ou si l'on veut implémenter un Strategy Pattern, il peut être utile de maitriser ces subtilités.

Code :
1
2
3
4
5
6
7
8
9
10
11
 
// ici casCritique sera initialisé quoi qu'il arrive, même si l'on ne s'en sert jamais
 
if(uneChanceSurUnMilliard === true){
    function casCritique(){
        // initialisation complexe très couteuse
    }
}
else{
    // NOOP
}
Code :
1
2
3
4
5
6
7
8
9
10
11
 
// ici casCritique (enfin, la valeur de la variable casCritique pour être exact) sera initialisé une fois sur un milliard
 
if(uneChanceSurUnMilliard === true){
    var casCritique = function casCritique(){
        // initialisation complexe très couteuse
    }
}
else{
    // NOOP
}
Bon après dans la pratique 99% du temps, OSEF.
TheGwy est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 12/12/2011, 16h13   #10
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 872
Points : 1 381
Points : 1 381
Clap Clap Clap.

Tu viens de m'apprendre qqe chose que je ne connaissais mais ABSOLUMENT pas en javascript.

Je viens donc de lire un excellent article à ce sujet : http://kangax.github.com/nfe/


Donc comme tu le dis, ce n'est pas du tout pareil car :

Code :
1
2
3
try{alpha(); }
catch(e){alert("error: alpha");}
function alpha(){alert(' exec alpha');}
ne provoquera pas d'erreur.

tandis que :

Code :
1
2
3
try{alpha(); }
catch(e){alert("error: alpha");}
var alpha = function alpha(){alert(' exec alpha');}
en provoquera.





edit:
Un autre exemple impressionant donné dans l'article :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Never do this!
// Some browsers will declare `foo` as the one returning 'first', 
// while others — returning 'second'
if(true) {
  function foo() {
    return 'first';
  }
}
else {
  function foo() {
    return 'second';
  }
}
alert(foo());
sous chrome, j'ai bien "second" qui s'affiche.
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/12/2011, 16h45   #11
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 872
Points : 1 381
Points : 1 381
je m'amuse comme un fou depuis qqes minutes avec ça, en fait ça peut avoir des conséquence effroyable pour ceux qui travaillent à plusieurs sur un gros projet sans savoir ce qui précède. (par exemple si chaque partie peut écrasser toutes les variables précédentes .. surtout une variable nommé "tmp" par exemple)

Code :
1
2
3
4
5
6
7
// CODE INCONNU PRECEDENT
var tmp = function(){alert('piège');};
 
// CODE EN COURS ..
function tmp(){alert('tmp');};
// affichera "piège"
tmp();

ou plus tordu :
Code :
1
2
3
4
5
6
7
// CODE INCONNU PRECEDENT
var tmp = (function(tmp){return function(){tmp();};})(tmp);
 
// CODE EN COURS ..
function tmp(){alert(arguments.callee == tmp);};
// affichera "false"
tmp();


edit: en version plus extrême pour surcharger une méthode qui n'existe pas encore (enfin je veux dire qui se trouve en tout début de code) :

Code :
1
2
3
4
5
6
7
8
// CODE INCONNU PRECEDENT
var tmp = (function(tmp){return function(){tmp.apply(this,arguments);};})(tmp);
 
// CODE EN COURS ..
var code = Math.random();
function tmp(c){ if(c==code) alert(arguments.callee == tmp);};
// affichera "false"
tmp(code);
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/12/2011, 17h52   #12
Membre régulier
 
Inscription : décembre 2007
Messages : 61
Détails du profil
Informations forums :
Inscription : décembre 2007
Messages : 61
Points : 83
Points : 83
Huhum, je vois que tu es allé puiser l'information directement à la meilleure source.

Les articles de kangax sont effectivement la référence absolue sur ce sujet.

Si cela t'intéresse tant que ça je te conseille la génialissime série d'articles "ECMA-262-3 in detail" de Dmitry Soshnikov.
Notamment les deux premiers chapitres qui expliquent toutes les bases et mécanisme internes à l'origine de ces subtilités :
http://dmitrysoshnikov.com/ecmascrip...tion-contexts/

Dans un autre registre tu as aussi cet autre article de kangax qui explique quelques différences entre les variables et les propriétés selon les types de contextes d'execution. (je te conseille de lire préalablement les deux premiers chapitres de soshnikov pour bien tout comprendre, mais tu peux faire sans).

http://perfectionkills.com/understanding-delete/
TheGwy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 12/12/2011, 21h25   #13
Membre expérimenté
 
Duke Jikel
Inscription : mai 2010
Messages : 340
Détails du profil
Informations personnelles :
Nom : Duke Jikel

Informations forums :
Inscription : mai 2010
Messages : 340
Points : 548
Points : 548
Et sinon le très bon javascript.info a un article dessus :
http://javascript.info/tutorial/func...nd-expressions
dukej est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/12/2011, 03h26   #14
Membre Expert
 
Avatar de Willpower
 
Homme Boris Dessy
sans emploi
Inscription : décembre 2010
Messages : 872
Détails du profil
Informations personnelles :
Nom : Homme Boris Dessy
Localisation : Belgique

Informations professionnelles :
Activité : sans emploi

Informations forums :
Inscription : décembre 2010
Messages : 872
Points : 1 381
Points : 1 381
je suis devenu accro


Code :
1
2
3
4
5
6
7
8
9
10
// hook all declarations
(function(f,i){for(i in window)
if("sessionStorage"!=i && typeof (f=window[i]) == 'function' && !f.toString().match(/\[native code\]/) )
window[i] = (function(f,n){return function(){alert(n+' hooked');f.apply(this,arguments);};})(f,i);})();
 
// test code here
function alpha(){
	document.write('alpha<br/>');
}
alpha();
Willpower est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 22h16.


 
 
 
 
Partenaires

Hébergement Web