際際滷

際際滷Share a Scribd company logo
Treviso JS Meetup:
Cattiveabitudinie
Lineeguida
Anti-patterns
(ovvero situazioni da evitare)
Dichiarare variabili senza il "var"
Dichiarando variabili senza il var, automaticamente
andiamo a definirle come Globali.
Da evitare!
name="Paperino";
function stampaPaperino() {
name ="Paperino";
console.log(name);
}
Utilizzando il "var", lo scope (ambiente dove vive la
variabile) diventa quello della funzione in cui 竪 definita.
Corretto!
var name="Paperino";
function stampaPaperino() {
var name ="Paperino";
console.log(name);
}
var a = b = 0;
In questo caso l'interprete riscrive il codice in questo modo:
quindi "b" 竪 globale.
Da evitare!
b = 0;
var a = b;
Questo pattern prevede di dichiarare tutte le variabili
utilizzando un solo "var".
Corretto!
var a = 0,
b = 0;
Sparpagliare variabili all'interno di
una funzione
"pluto" e "paperino" sono dichiarate in due momenti
separati all'interno della funzione.
Da evitare!
function plutoAiutaPaperino() {
var pluto = new Pluto();
pluto.corre();
pluto.mangia();
...
var paperino = new Paperino();
pluto.aiuta(paperino);
}
Pi湛 leggibile e evitiamo problemi legati all' "hoisting".
Corretto!
function plutoAiutaPaperino() {
var pluto = new Pluto(),
paperino = new Paperino();
pluto.corre();
pluto.mangia();
pluto.aiuta(paperino);
}
For loops scritti male
"i" in questo caso 竪 globale. Se "list" 竪 un array
particolarmente grande il dover recuperare ad ogni
iterazione il valore di "list.length" rallenta il codice.
Da evitare!
for(i = 0; i < list.length; i++) {
// do something
};
"list.length" in questo caso viene "cachato" nella variabile
"len". ( )
Corretto!
for(var i = 0, len = list.length; i < len; i++) {
// do something
};
http://jsperf.com/loops
Eval is evil
"eval" esegue il codice javascript inserito in una stringa.
Da evitare!
eval('var i = "Welcome Hackers!"; alert(i);');
Usare i costruttori predefiniti al
posto della sintassi "literal".
Qualsiasi cosa in Javascript 竪 un Object, il linguaggio mette
a disposizione dei costruttori che ereditano da Object
implementando nuove funzionalit. "new Array()" ad
esempio crea un oggetto di tipo Array con delle funzionalit
come "pop","push","shift", etc.
Da evitare!
var disney = new Array("Pippo","Topolino","Paperino");
Corretto!
var disney = ["Pippo","Topolino","Paperino"];
Questa sintassi 竪 molto pi湛 pulita e condivisa da gran parte
dei linguaggi di programmazione.
Inquinamento Globale
E' buona norma evitare di definire variabili o funzioni nello
"scope globale" perch竪 sono accessibili e modificabili in
qualsiasi punto dell'applicazione.
C'竪 il rischio che vengano accidentalmente sovrascritte da
altri programmatori o plugin esterni e rendono il codice
difficile da mantenere.
Da evitare!
<script>
var pluto = new Pluto(),
plutoHouse = new DogHouse({color:red,material:'wood', size: [100,100
function loadPlutoHouse() {
return pluto.load(house);
}
</script>
Tutte le variabili definite nel frammento di codice sopra-
riportato sono globali perch竪 non sono definite all'interno di
una funzione.
Usare una funzione che viene definita e subito invocata crea
uno "scope isolato". Variabili e funzioni esistono solo
all'interno dell' IIFE.
Corretto!
<script>
// IIFE = Immediately-Invoked Function Expression
(function(document, window, undefined){
var pluto = new Pluto(),
plutoHouse = new DogHouse({color:red,material:'wood', size: [100
function loadPlutoHouse() {
return pluto.load(house);
}
})(document,window);
</script>
Esempio in jQuery
<script>
// IIFE = Immediately-Invoked Function Expression
(function($,document, window){
//code immediately executed goes here
$(function(){
//code executed on document ready goes here
});
})(jQuery, document,window, undefined);
</script>
jQuery
Anti-patterns
Evviva i costruttori!
Ogni volta che usiamo $('...') viene creato un nuovo oggetto
jQuery parsando il DOM e cercando l'elemento
corrispondente. Assolutamente poco performante.
Da evitare!
$('button.confirm').on('click', function() {
// Do it once
$('.modal').modal();
// And once more
$('.modal').addClass('active');
// And again for good measure
$('modal').css(...);
});
jQuery ci permette di "concatenare" pi湛 funzioni al
medesimo oggetto $ perch竪 ogni funzione ritorna l'instanza
dell'elemento DOM jquerizzato.
Soluzione 1: Chaining
$('button.confirm').on('click', function() {
$('.modal')
.modal()
.addClass('active')
.css(...);
});
Salvare il riferimento all'oggetto jQuery per poi riusarlo nel
codice 竪 la soluzione ottimale. In particolare all'interno dei
listener evitiamo di dover "attraversare" il DOM ogni volta
che si scatena l'evento a cui l'ascoltatore 竪 associato.
Soluzione 2: Caching
var $buttonConfirm = $('button.confirm'),
$modal = $('.modal');
$background = $('.bg-overlay');
$buttonConfirm.on('click', function() {
$modal
.modal()
.addClass('active')
.css(...);
$background.removeClass('hidden');
});
L'inferno delle CallBack
Annidare callback porta a codice difficile da capire e
mantenere.
Da evitare!
$buttonConfirm.on('click', function() {
$overlay.fadeIn(400, function(){
$.ajax('/some/modal/content',{},function(data){
$overlay.html(data).slideUp(300, function() {
....
})
})
})
});
Portare le funzioni all'esterno aiuta la leggibilit.
Un p嘆 meglio
$buttonConfirm.on('click', showOverlay);
function showOverlay() {
$overlay.fadeIn(400, getOverlayDataFromServer);
}
function getOverlayDataFromServer() {
$.ajax('/some/modal/content',{}, updateOverlayContent);
}
function updateOverlayContent(data) {
$overlay.html(data).slideUp(300, function() {
....
})
}
Alcuni medoti jQuery ritornano direttamente un Deferred
object, 竪 possibile creare anche "azioni" custom che
utilizzano $.Deferred.
Deferred Objects
$buttonConfirm.on('click', function(e){
$.when(showOverlay())
.then(getOverlayDataFromServer())
.done(updateOverlayContent(data))
.fail(function(){ alert("Something went wrong!") });
});
function showOverlay() {
// $.fn.fadeIn has a promise() method defined so it works like a deferred
return $overlay.fadeIn(400);
}
function getOverlayDataFromServer() {
return $.ajax('/some/modal/content');
}
function updateOverlayContent(data) {
Lineeguida
(Tools per scrivere Javascript pulito)
'use strict';
Con questa dicitura abilitiamo la modalit "Strict Mode":
per alcuni sbagli (o cattive abitudini) normalmente accettati
dall'interprete JS vengono sollevati errori.
'use strict';
function myFunction() {
'use strict';
//...
}
Usare un linter JS: JsHint
Pu嘆 essere usato sia come plugin nell'editor di testo sia
all'interno del vostro task manager (Grunt/Gulp).
Esempio
Scegliere una StyleGuide e usare
JSCS
Ogni programmatore ha le sue abitudini, giuste o sbagliate
che siano.
Scegliere una styleguide e condividerla con il team di
progetto 竪 fontamentale per avere un codice omogeneo e
"stilisticamente" pulito.
AirBnB
Google
jQuery
Idiomatic.js
JSCS

More Related Content

Cattive abitudini e-lineeguida

  • 4. Dichiarando variabili senza il var, automaticamente andiamo a definirle come Globali. Da evitare! name="Paperino"; function stampaPaperino() { name ="Paperino"; console.log(name); }
  • 5. Utilizzando il "var", lo scope (ambiente dove vive la variabile) diventa quello della funzione in cui 竪 definita. Corretto! var name="Paperino"; function stampaPaperino() { var name ="Paperino"; console.log(name); }
  • 6. var a = b = 0;
  • 7. In questo caso l'interprete riscrive il codice in questo modo: quindi "b" 竪 globale. Da evitare! b = 0; var a = b;
  • 8. Questo pattern prevede di dichiarare tutte le variabili utilizzando un solo "var". Corretto! var a = 0, b = 0;
  • 10. "pluto" e "paperino" sono dichiarate in due momenti separati all'interno della funzione. Da evitare! function plutoAiutaPaperino() { var pluto = new Pluto(); pluto.corre(); pluto.mangia(); ... var paperino = new Paperino(); pluto.aiuta(paperino); }
  • 11. Pi湛 leggibile e evitiamo problemi legati all' "hoisting". Corretto! function plutoAiutaPaperino() { var pluto = new Pluto(), paperino = new Paperino(); pluto.corre(); pluto.mangia(); pluto.aiuta(paperino); }
  • 13. "i" in questo caso 竪 globale. Se "list" 竪 un array particolarmente grande il dover recuperare ad ogni iterazione il valore di "list.length" rallenta il codice. Da evitare! for(i = 0; i < list.length; i++) { // do something };
  • 14. "list.length" in questo caso viene "cachato" nella variabile "len". ( ) Corretto! for(var i = 0, len = list.length; i < len; i++) { // do something }; http://jsperf.com/loops
  • 16. "eval" esegue il codice javascript inserito in una stringa. Da evitare! eval('var i = "Welcome Hackers!"; alert(i);');
  • 17. Usare i costruttori predefiniti al posto della sintassi "literal".
  • 18. Qualsiasi cosa in Javascript 竪 un Object, il linguaggio mette a disposizione dei costruttori che ereditano da Object implementando nuove funzionalit. "new Array()" ad esempio crea un oggetto di tipo Array con delle funzionalit come "pop","push","shift", etc. Da evitare! var disney = new Array("Pippo","Topolino","Paperino");
  • 19. Corretto! var disney = ["Pippo","Topolino","Paperino"]; Questa sintassi 竪 molto pi湛 pulita e condivisa da gran parte dei linguaggi di programmazione.
  • 21. E' buona norma evitare di definire variabili o funzioni nello "scope globale" perch竪 sono accessibili e modificabili in qualsiasi punto dell'applicazione. C'竪 il rischio che vengano accidentalmente sovrascritte da altri programmatori o plugin esterni e rendono il codice difficile da mantenere.
  • 22. Da evitare! <script> var pluto = new Pluto(), plutoHouse = new DogHouse({color:red,material:'wood', size: [100,100 function loadPlutoHouse() { return pluto.load(house); } </script> Tutte le variabili definite nel frammento di codice sopra- riportato sono globali perch竪 non sono definite all'interno di una funzione.
  • 23. Usare una funzione che viene definita e subito invocata crea uno "scope isolato". Variabili e funzioni esistono solo all'interno dell' IIFE. Corretto! <script> // IIFE = Immediately-Invoked Function Expression (function(document, window, undefined){ var pluto = new Pluto(), plutoHouse = new DogHouse({color:red,material:'wood', size: [100 function loadPlutoHouse() { return pluto.load(house); } })(document,window); </script>
  • 24. Esempio in jQuery <script> // IIFE = Immediately-Invoked Function Expression (function($,document, window){ //code immediately executed goes here $(function(){ //code executed on document ready goes here }); })(jQuery, document,window, undefined); </script>
  • 27. Ogni volta che usiamo $('...') viene creato un nuovo oggetto jQuery parsando il DOM e cercando l'elemento corrispondente. Assolutamente poco performante. Da evitare! $('button.confirm').on('click', function() { // Do it once $('.modal').modal(); // And once more $('.modal').addClass('active'); // And again for good measure $('modal').css(...); });
  • 28. jQuery ci permette di "concatenare" pi湛 funzioni al medesimo oggetto $ perch竪 ogni funzione ritorna l'instanza dell'elemento DOM jquerizzato. Soluzione 1: Chaining $('button.confirm').on('click', function() { $('.modal') .modal() .addClass('active') .css(...); });
  • 29. Salvare il riferimento all'oggetto jQuery per poi riusarlo nel codice 竪 la soluzione ottimale. In particolare all'interno dei listener evitiamo di dover "attraversare" il DOM ogni volta che si scatena l'evento a cui l'ascoltatore 竪 associato. Soluzione 2: Caching var $buttonConfirm = $('button.confirm'), $modal = $('.modal'); $background = $('.bg-overlay'); $buttonConfirm.on('click', function() { $modal .modal() .addClass('active') .css(...); $background.removeClass('hidden'); });
  • 31. Annidare callback porta a codice difficile da capire e mantenere. Da evitare! $buttonConfirm.on('click', function() { $overlay.fadeIn(400, function(){ $.ajax('/some/modal/content',{},function(data){ $overlay.html(data).slideUp(300, function() { .... }) }) }) });
  • 32. Portare le funzioni all'esterno aiuta la leggibilit. Un p嘆 meglio $buttonConfirm.on('click', showOverlay); function showOverlay() { $overlay.fadeIn(400, getOverlayDataFromServer); } function getOverlayDataFromServer() { $.ajax('/some/modal/content',{}, updateOverlayContent); } function updateOverlayContent(data) { $overlay.html(data).slideUp(300, function() { .... }) }
  • 33. Alcuni medoti jQuery ritornano direttamente un Deferred object, 竪 possibile creare anche "azioni" custom che utilizzano $.Deferred. Deferred Objects $buttonConfirm.on('click', function(e){ $.when(showOverlay()) .then(getOverlayDataFromServer()) .done(updateOverlayContent(data)) .fail(function(){ alert("Something went wrong!") }); }); function showOverlay() { // $.fn.fadeIn has a promise() method defined so it works like a deferred return $overlay.fadeIn(400); } function getOverlayDataFromServer() { return $.ajax('/some/modal/content'); } function updateOverlayContent(data) {
  • 34. Lineeguida (Tools per scrivere Javascript pulito)
  • 36. Con questa dicitura abilitiamo la modalit "Strict Mode": per alcuni sbagli (o cattive abitudini) normalmente accettati dall'interprete JS vengono sollevati errori. 'use strict'; function myFunction() { 'use strict'; //... }
  • 37. Usare un linter JS: JsHint
  • 38. Pu嘆 essere usato sia come plugin nell'editor di testo sia all'interno del vostro task manager (Grunt/Gulp).
  • 40. Scegliere una StyleGuide e usare JSCS
  • 41. Ogni programmatore ha le sue abitudini, giuste o sbagliate che siano. Scegliere una styleguide e condividerla con il team di progetto 竪 fontamentale per avere un codice omogeneo e "stilisticamente" pulito. AirBnB Google jQuery Idiomatic.js
  • 42. JSCS