Bonjour,
Attention : DÉBUTANT en Js.
Je me mets au Js, côté serveur (donc avec Node). L'envie d'apprendre un nouveau et avec lequel je peux tout faire si j'en ai envie, du script shell au web côté client. Et comme je viens de la vieille école (C++/C#), j'essaie de faire les choses bien.
Parmi la pléthore de moyens pour créer des objets en Js, j'ai choisi d'utiliser la notation littérale et les "factories" pour créer les instances. Ca donne donc un truc comme ça :
// ES6 only
'use strict';
// The base object, "object literal" syntax
let animal2 = {
// public member
animalType: 'animal',
// public method
describe() {
return `This is "${this.animalType}"`;
}
};
// factory function which serves 2 purposes:
// - encapsulation, that's where private things are declared thanks to closures
// - the "real" object creation, this prevents to use "new" which is not really Js-ish
let afc = function afc() {
// private member
let priv = "secret from afc";
return Object.create(animal2, {
// Object customisation
animalType: { value: 'animal with create'},
// object extension. The new objects created here get 3 new members:
// - a private member
// - a new property
// - a new method to access the private member
// new public member
color: { value: 'green' },
secret: {
get: function () { return priv; },
set: function (value) { priv = value; },
},
KO1() {
console.log("KO1");
},
KO2: function() {
console.log("KO2");
}
});
}
// creation of an animal instance
let tac = afc();
Désolé si le code est en Anglais, je fais ça depuis 20 ans, et j'ai pas envie de changer !
Ce code fonctionne plutôt pas mal. Cependant je n'arrive pas appréhender la syntaxe pour écrire une méthode qui soit autre chose qu'un accesseur, mais qui permette néanmoins la manipulation de membres privés. Je mets ici 2 exemples de syntaxe qui me viennent à l'esprit, mais quand je lance un tel code avec Node, j'obtiens "KOx is not a function".
J'apprécie tous les conseils, bonnes pratiques, etc … et une proposition pour implémenter cette satanée fonction.
Merci.
# sans prétentions
Posté par mh-cbon . Évalué à 2.
J'ai bien peur de ne pouvoir te renseigner sur les bonnes pratiques… je doutes de ne pas dire plus de bêtises qu'autre chose, et je ne crée plus que très rarement des classes en js.
Ceci dit, je propose cette syntaxe,
tldr; ma préférence à moi
- pas d'Object.create,
- si je dois faire un getter, je fais une variable définie dans un scope et une méthode pour y accéder
- si je veux faire une propriété publique, je fais une propriété d'objet. Si je venais à avoir des problèmes et que j'avais soudainement le besoin de capturer le set/get, je me tournerais vers Object.defineProperty
Voir,
- https://nodejs.org/docs/latest/api/util.html#util_util_inherits_constructor_superconstructor
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
Finalement, je n'aurais pas utiliser es6. C'est mon gout comme c'est ton choix, mais c'est la mode pas comme evelyne thomas.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à 1.
J'oubliais, pour connaitre le passCode de chacun de ces animaux,
et non cela n'affichera pas un booléen, et c'est très bien !
[^] # Re: sans prétentions
Posté par romu . Évalué à 1.
Merci pour ta proposition.
ES6 pour moi, c'est pas une question de mode, mais comme je débute, autant prendre le dernier standard.
La syntaxe par fonction constructeur, j'aime moyen, surtout parce qu'elle oblige à utiliser "new" qui me semble en dehors de clous de la philosophie Js, mais je peux me tromper hein ;-)
Mon but n'est d'ailleurs pas de créer des hiérarchie d'objets, je suis assez partisan de "l'héritage c'est le mal". Mais simplement de pouvoir créer des instances, avec de l'encapsulation public/privé.
Cela dit, je vois comment tu fais le truc, et ça me donne l'idée d'ajouter les fonctions autres que les accesseurs dans la factory, juste après la création de l'instance. C'est pas beau, mais ça devrait marcher.
Bancal ce langage quand même…
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à 0.
c'est un outil du langage à toi de de le comprendre et de t'en servir au mieux,
quelques exemples d'utilisation de new,
- https://github.com/feross/webtorrent/blob/master/index.js
- https://github.com/watson/bonjour/blob/master/index.js
Le contre exemple qui va bien
- https://github.com/mafintosh/multicast-dns/blob/master/index.js
dogmatism is evil ;)
Il y a un cap à passer sur ce sujet des classes et constructeurs.
Après cela, le langage reste bancal :D
Mais comme il donne des possibilités sans toute la lourdeur d'un langage hiérarchisé, j'apprécie.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à 1.
Pour revenir sur es6, l'un ou l'autre importe peu, par contre, ton utilisation de la fonction fléchée KO1, me laisse perplexe.
Faudrait le tester mais je soupçonne que le this de KO1 === afc et non ta bête…. A confirmer !
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Fonctions/Fonctions_fl%C3%A9ch%C3%A9es
bref, es6, mon avis très personnel, ça met encore plus de souk là où c'était déjà un joyeux désordre.
[^] # Re: sans prétentions
Posté par romu . Évalué à 1.
Oulà, je crois être encore loin de maitriser les fonctions fléchées. Et mes KOx n'en sont pas (ou alors j'ai raté un truc), juste 2 exemples d'écrire les fonctions qui me semblaient correctes…et qui ne le sont apparemment pas.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à 0.
et bien justement, il se trouve que tu as écris une fonction fléchée !
regardes ton code initial,
KO1 est une fonction fléchée ! Enfin, ça y ressemble imho.
Le truc étant que comme ni Object.create, ni l'objet d'extension {animalType…} ne définisse de scope, je suppute que le this sera affecté a afc, mais cela reste à vérifier.
Ceci dit, depuis le début ta syntaxe de KO1 me pose un souci.
Essaies de lire ces papiers, ils m'ont l'air plus appropriés à ce que tu souhaites écrire
comme quoi c'est le souk ; )
[^] # Re: sans prétentions
Posté par romu . Évalué à 1.
Je crois tu fais erreur, c'est juste la notation litérale avec ES6 :
…pas une fonction fléchée.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à 0.
Fonction littérale ? euh ouais peut être xd ou peut être pas xb
La mdn n'en fait pas référence,
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
Une histoire de souk ; )
Et si je reprends https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Fonctions/Fonctions_fl%C3%A9ch%C3%A9es
Je ne vois pas de contre indication à penser que c'est une Ffléchée, la fonction est anonyme, la syntaxe est respectée, elle est attachée a animalType2.describe.
Perso je me suis jamais posé ce genre de questions, en fait.
Quand je fais une fonction,
je me demande si je veux lui donner un nom, pour mieux debugger,
et je regarde son scope, pour savoir si ça colle.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à 0.
si je trouves je te posterais un lien vers des bonnes pratiques JS qui me semble sont plus importante,
D'ici là tu peux te tenter
- https://github.com/stevekwan/best-practices/blob/master/javascript/best-practices.md
- http://jstherightway.org/
Mais ce n'est pas exactement le genre concision que j'aurais voulu avoir, désolé.
[^] # Re: sans prétentions
Posté par romu . Évalué à 2. Dernière modification le 01 avril 2016 à 09:21.
Si si, c'est l'écriture qu'on trouve aussi dans le MDN, par exemple ici : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_Types#Object_literals.
Par contre, et tu touche un point important, je ne me suis pas posé la question de savoir si avec cette écriture, la fonction est anonyme ou pas.
Je vais tester ça, ça me fera progresser. Merci !
Concernant les "Best Practises", merci pour les liens, je verrai ça quand j'aurais fini le bouquin de Crockford.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à -1.
au risque de paraphraser tes lectures et ta compréhension,
Ta remarque initiale portait sur la notion de fonction littérale.
Hors le lien que tu pointes porte sur la notion d'objet littérale.
En me basant sur la définition suivante de la mdn,
Pour en revenir sur la notion de fonction littérale, j'avoue que malgré mes recherches je n'ai pas de certitude. Je suspectes que c'est une notion importée.
Autre chose, Ffléché est obligatoirement anonyme, cela fait partie de sa définition (mdn again),
Des questions intéressantes !
[^] # Re: sans prétentions
Posté par romu . Évalué à 1.
Merci. D'ailleurs, quelqu'un ma donné la syntaxe correcte pour ajouter les fonctions dans ma factory, mais c'est assez lourdingue. Je vais tenter autre chose, plus simple.
Cela dit, de nos discussions, j'ai sorti quelque chose qui met en exergue tes remarques, notamment sur les fonctions anonymes.
Donc ok, la première forme est anonyme. Mais le "this" est correctement attaché. Je n'ai pas l'expérience suffisante de Js pour juger la réelle différence entre les 2. Mais au moins, maintenant, je sais. A l'écriture cependant, y a pas photo je trouve.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à -1.
J'ai l'impression que la déclaration de fact2 en tant que fonction est oubliée. Il ne connait plus que la méthode animal.fact2.
Aussi, si tu jettes des exceptions depuis fact / fact2, il renvoies des jolies stack traces (ex.stack) qui remonte les noms de méthode de l'objet.
Bref, je ne vois pas de différences notable à mon humble niveau.
je rajoutes un exemple au cas où cela t'en soulève une, de gauche ou de droite.
[^] # Re: sans prétentions
Posté par romu . Évalué à 1.
Ah bonne idée ça de tester avec les exceptions. J'y avais pas pensé et c'est surement là que je vais pouvoir faire quelques tests intéressants. Encore merci du coup, tu m'auras permis de bien progresser dans ce long chemin qu'est Js.
Et dire qu'on lit partout que Js est "facile", quelle blague !
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à -1.
et moi qui pensais justement "et encore ce n'est que this.." y'a pas 5 minutes : )
Juste au cas où, jettes un œil aussi à bind / call / apply et self pour en finir, je crois, avec this.
Restera plus que les streams, les promesses, la pseudo programmation fonctionnelle, la boucle d' évènements (nextTick, setTimeout(fn,0), setImmediate), éviter le callback hell (return first), faire un paquet npm, le semver, les frameworks de tests, les opérations de lint, la browserification, la chaine de build (grunt, gulp, npm sripts ect) et d'autres trucs que j'oublie probablement !
[^] # Re: sans prétentions
Posté par romu . Évalué à 1.
Ouais, tout ça, faut être motivé !
Le callback hell, c'est justement pour ça que je développe un truc, je viendrai en parler quand je serai plus avancé sur la question.
Un grand merci.
[^] # Re: sans prétentions
Posté par mh-cbon . Évalué à 0.
tu m'intrigues : ) on a eu le droit à pas mal de littérature déjà : http://callbackhell.com/ voir aussi le dernier né https://www.youtube.com/watch?v=a8W5VVGO-jA
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.