Oo Javascript
-
Upload
maraexception -
Category
Technology
-
view
1.578 -
download
1
Transcript of Oo Javascript
OBJECT ORIENTED JAVASCRIPTguida per un mondo migliore
Davide Cerbo
http://jesty.it
Stefano Linguerri
http://www.eljeko.net
Una cattiva impressione
L'unione fa la forza
JAVASCRIPT + PROTOTYPE
Perch usare Prototype
Codice pi breve
Sintassi pi chiara
Gestisce le incompatibilit trai vari browser
Fornisce diverse funzioni e oggetti di utilit
Permette lo sviluppo di Javascript non intrusivo
E' complementare a Script.aculo.us
Qualcosa di utile
$('...') come getDocumentById('...') ma ritorna un Element di Prototype
$$('...') Selettore CSS
$$('.menu #submenu)
ritorna tutti gli elementi che hanno class submenu all'interno
di
un elemento che ha id menu
Ajax.request(Url, {...}) Esegue una richiesta AJAX, le graffe
conterranno le opzioni della request:
new Ajax.Request(url, {onSuccess: function(transport) {...});
Esistono anche altri metodi come: updater e periodicalUpdater.
Template Permette di definire delle stringe
parametrizzabili
var t = new Template('Name: #{name}, surname: #{surname}');
var show = {name: 'Davide', surname: 'Cerbo'};
t.evaluate(show); //return Name: Davide, surname: Cerbo
Observer Permette di osservare gli eventi su un elemento
$('id').observe('click', function(element){...});
Di cosa abbiamo bisogno?
Per considerare JAVASCRIPT un linguaggio Object Oriented abbiamo
bisogno di:
Strutture dati complesse
Classi
Interfacce
Polimorfismo
Strutture dati complesse
Hash var h = new Hash();
h.set(key, value);
h.get(key); //return value
h.unset(key);
h.toQueryString() //return key1=v1&key2=v2&...
Enumerable sono liste iterabili con metodi come
each, map, find, select, etc...
$A(...).each(function(e){ alert(e.id); });
$$('...') restituisce un Enumerable
Sono tutte CLOSURE
Questione di classe
Javascript Classico
var Person = Class.create();Person.prototype = { initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; }};var jack = new Person(Jack Maffai);jack.say(Hi Boy);//return Jack Maffai: Hi boy!
Prototype
var Person = Class.create({ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; }});
var jack = new Person(Jack Maffai);jack.say(Hi Boy);//return
Jack Maffai: Hi boy!
Estendiamo
Javascript classico
var Pirate = Class.create();Pirate.prototype = Object.extend(new Person(), { say: function(message) { return this.name + ': ' + message + ', yarr!'; }});
Prototype
var Pirate = Class.create(Person, { say: function($super, message) { return $super(message) + ', yarr!'; }});
new Pirate(Jack Maffai).say(Hi Boy!);//say return: Hi Boy!, yarr!
Interfacce?
Non ci sono e basta!
Accontentiamoci delle classiE ricordiamoci che in Javascript vige la regola:
If it walks like a duck and quacks like a duck, I would call it a duck.
Al volo
var john = new Pirate('Long John');
john.sleep();// -> ERROR: sleep is not a method
Person.addMethods({ sleep: function() { return this.say('ZzZ'); }});
john.sleep();// -> "Long John: ZzZ, yarr!"
Il metodo viene aggiunto a tutte le istanze e le sottoclassi di Pirate
DOMinare con Prototype
Questo approccio deve cambiare il nostro modo di vedere la programmazione Javascript
PROGRAMMAZIONE
FUNZIONALE
Esempio
HTML:
Script di startup:
// $('simonboard') indica la tabella// 5 il numero massimo di
quadrati da colorare
new Board($('simonboard')).start(5);
Il colore predefinito per il quadrato
Tabella da utilizzare
Lo script
var Tile = Class.create({ initialize: function(color, element) { this.color = color; this.element = element; }, blink: function() { this.element.style.backgroundColor = this.color; new Effect.Opacity(this.element, {duration:2, from:1.0, to:0}); // Scrip.aculo.us }});
var Board = Class.create({ initialize: function(boardElement) { this.tiles = boardElement.select("td").map(function(element){return new Tile(element.id, element);}); },//numero massimo di blocchi da colorare start: function(steps) { var boardSize = this.tiles.length; var tempTiles = this.tiles; //serve per problemi di scope si corregge usando la funzione bind() $R(1, steps).each(function(i){ //funzione di Prototype che riempe un array con un range di valorivar index = Math.ceil(Math.random() * boardSize);var tile = tempTiles[index-1];window.setTimeout(function() { tile.blink(); }, 500 * index);}); }});
Un concetto utile: bind
start: function(steps) { var boardSize = this.tiles.length; $R(1, steps).each(function(i) {var index = Math.ceil(Math.random() * boardSize);var tile = this.tiles[index-1];window.setTimeout(function() { tile.blink(); }, 500 * index);}.bind(this)); }
Il bind serve ad evitare problemi di scope, se lo avessi omesso il this considerato dalla funzione sarebbe stato l'oggeto window.
In Javascript tutte le funzioni sono eseguite in un determinato contesto e questo referenziabile tramite la parola chiave da this
Le funzioni utilizzate come closure sono funzioni globali, quindi hanno il contesto globale
Strumenti utili
Log4J
Debugger
JUnit
JMock e simili
BlackbirdJS
Firebug
JSUnit
JSMock
Siamo abituati ad avere una marea di strumenti a nostra disposione javascript non ci deluder!
Logging: Log4J BlackbirdJS
Debug: Java Debugger Firebug
Unit Test: JUnit JSUnit [1]
Unit Test: JUnit JSUnit [2]
Unit Test: JUnit JSUnit [3]
Unit Test: JUnit JSUnit [4]
MockObject: JMock JSMock [1]
Classe sotto test (CUT)
function Worker() {this.getValue = function() { /* ... */}this.isFinished = function() {/* ... */}}
Fixture
function doWork(worker) {if(worker.isFinished()) {return worker.getValue();} else {return null;}}
Test
function test_doWork() {var mControl = new MockControl();worker = mControl.createMock(Worker);worker.expects().isFinished().andReturn(true);worker.expects().getValue().andReturn('hello');var result = doWork(worker);assertEquals('hello', result);mControl.verify();}
MockObject: JMock JSMock [2]
Classe sotto test (CUT)
function Worker() {this.getValue = function() { /* ... */}this.isFinished = function() {/* ... */}}
Fixture
function doWork(worker) {if(worker.isFinished()) {return worker.getValue();} else {return null;}}
Test
function test_doWork_null() {var mControl = new MockControl();worker = mControl.createMock(Worker);worker.expects().isFinished().andReturn(false);var result = doWork(worker);assertNull(result);mControl.verify();}
Conclusioni
Bibliografia & Links
www.prototypejs.org
http://script.aculo.us
http://www.prototypejs.org/learn/class-inheritance
http://www.gscottolson.com/blackbirdjs/
http://getfirebug.com/js.html
http://www.jsunit.net/
http://jsmock.sourceforge.net/
http://www.infoq.com/articles/javascript-tdd
http://en.wikipedia.org/wiki/Duck_typing
http://www.prototypejs.org/api/function/bind
http://alternateidea.com/blog/articles/2007/7/18/javascript-scope-and-binding
Q&A
JS?
http://jesty.it
[email protected]@pronetics.it
Muokkaa otsikon tekstimuotoa napsauttamalla
Muokkaa jsennyksen tekstimuotoa napsauttamallaToinen jsennystasoKolmas jsennystasoNeljs jsennystasoViides jsennystasoKuudes jsennystasoSeitsems jsennystasoKahdeksas jsennystasoYhdekss jsennystaso