Pobieranie prezentacji. Proszę czekać

Pobieranie prezentacji. Proszę czekać

Realizacja Aplikacji Internetowych JavaScript. Quiz [] + [] [] + {} [0]+1 [0]-1 A = [0] A == A A == !A A = [null, undfined, [] ] A ==,,

Podobne prezentacje


Prezentacja na temat: "Realizacja Aplikacji Internetowych JavaScript. Quiz [] + [] [] + {} [0]+1 [0]-1 A = [0] A == A A == !A A = [null, undfined, [] ] A ==,,"— Zapis prezentacji:

1 Realizacja Aplikacji Internetowych JavaScript

2 Quiz [] + [] [] + {} [0]+1 [0]-1 A = [0] A == A A == !A A = [null, undfined, [] ] A ==,,

3 JavaScript vs ECMAScript JavaScript is nie jest związany z Javą JavaScript is nie jest związany z Javą Wprowadzony w przegladarce Netscape w XII 1995 Wprowadzony w przegladarce Netscape w XII 1995 Najbardziej popularny język programowania na świecie ? Najbardziej popularny język programowania na świecie ? MS wyprodukował zbliżony język: JScript MS wyprodukował zbliżony język: JScript Oba języki bazują na standardzie ECMAScript wprowadzonym przez European Computer Manufacturers Association (3 wyd w XII 1999) Oba języki bazują na standardzie ECMAScript wprowadzonym przez European Computer Manufacturers Association (3 wyd w XII 1999) JavaScript i JScript są nadzbiorami ECMAScript JavaScript i JScript są nadzbiorami ECMAScript Są hostowane w przeglądarkach, ale nie tylko (Acrobat Forms, Node.js) Są hostowane w przeglądarkach, ale nie tylko (Acrobat Forms, Node.js)

4 Typy (pojedyncza wartość: ) Undefined (pojedyncza wartość: undefined ) (pojedyncza wartość: ) Null (pojedyncza wartość: null ) (wartości:, ) Boolean (wartości: true, false ) (niemutowalna sekwencja znaków Unicode, brak typu znakowego) String (niemutowalna sekwencja znaków Unicode, brak typu znakowego) (64-bitowa liczba zmiennoprzecinkowa, brak typu całkowitego, specjalne wartości i ) Number (64-bitowa liczba zmiennoprzecinkowa, brak typu całkowitego, specjalne wartości NaN i Infinity ) Object "...i to by było na tyle...". "...i to by było na tyle...".

5 Nowe operatory === === jest identyczny (wartość i typ) !== !== nie jest identyczny (wartość lub typ)

6 Zmienne Dwa poziomy granularności zakresu: globalne i funkcja (brak zakresu bloku) Dwa poziomy granularności zakresu: globalne i funkcja (brak zakresu bloku) Tylko zmienne defioniowane jako w obrebie funkcji mają zakres funkcji – inne są globalne. Nie na sensu używać bloków gdy nie są wymagane przez instrukcje złożone. Tylko zmienne defioniowane jako var w obrebie funkcji mają zakres funkcji – inne są globalne. Nie na sensu używać bloków gdy nie są wymagane przez instrukcje złożone. nie zaincjalizowane ex-plicite ma wartość var nie zaincjalizowane ex-plicite ma wartość undefined. nie jest typowane var nie jest typowane

7 Obiekty Referencjonalne kontenery par nazwa/wartość Referencjonalne kontenery par nazwa/wartość Nazwy: napisy (Jeśli treba wykonywan konwersja) Nazwy: napisy (Jeśli treba wykonywan konwersja) Wartości: dowolny typ danych (właczajac inne obiekty) Wartości: dowolny typ danych (właczajac inne obiekty) Nie trzeba implementować dostępu API (hashtable) Nie trzeba implementować dostępu API (hashtable) Właściwości tworzone w locie Właściwości tworzone w locie var myObj={};var myObj=new Object(); myObj.p1=blah;myObj[p1]=blah; var myObj={p1:new String(blah)}; Metody ? Metody ?

8 Obiekty Obiekty są w istocie tablicami haszowanymi z ładną składnią Można więc iterować po obiekcie... for (name in object) { if (object.hasOwnProperty(name)) { value = object[name]; } }

9 Obiekt Globalny Unikalny, pre-definiowany obiekt który zawiera wszytskie funkcje i zmienne nie zdefionowane wewnątrz innych funkcji lub obiektów Unikalny, pre-definiowany obiekt który zawiera wszytskie funkcje i zmienne nie zdefionowane wewnątrz innych funkcji lub obiektów W przeglądarkach implementacja, i pokazują na Obiekt Globalny W przeglądarkach implementacja this, window i self pokazują na Obiekt Globalny Wszystkie globalne funkcje i zmienne są zdefiniowane jako funkcje i zmienne Obiektu Globalnego Wszystkie globalne funkcje i zmienne są zdefiniowane jako funkcje i zmienne Obiektu Globalnego this.NaN=0; //changes value of NaN constant ! Jeśli zmienna/funkcja nie jest zdefiniowana w bieżącym zakresie jest poszukiwana w Obiekcie Globalnym Jeśli zmienna/funkcja nie jest zdefiniowana w bieżącym zakresie jest poszukiwana w Obiekcie Globalnym

10 Tablice Regularne obiekty (właściwości dostępne za pośrednictem nazw!) properties accessed via names!), ale okreslona klasa nazw (non- negative integers) właściwości traktowana inaczej Regularne obiekty (właściwości dostępne za pośrednictem nazw!) properties accessed via names!), ale okreslona klasa nazw (non- negative integers) właściwości traktowana inaczej Nie typowane (mogą zawierać wartości różnych typów) Nie typowane (mogą zawierać wartości różnych typów) Właściwość jest ustawiana na największy klucz całkowity w tablicy +1 Właściwość length jest ustawiana na największy klucz całkowity w tablicy +1 var myArr=[val0]; //myArr.length == 1 myArr[1]=val1;//myArr.length == 2 myArr[v2]=val2;//myArr.length == 2 myArr.2=val2;//nielegalne

11 Funkcje Obiekty typu first-class ze skojarzonym kodem i możliwą operacją call Obiekty typu first-class ze skojarzonym kodem i możliwą operacją call Składnia Składnia function func(x) {alert(x);} Operator (nazwa f. jest opcjonalna – f.anonimowe) Operator (nazwa f. jest opcjonalna – f.anonimowe) var func=function(x) {alert(x);}; Konstruktor (nie ma słowa function) Konstruktor (nie ma słowa function) var func=new Funkcja(x,alert(x);); Wsparcie dla zmiennej liczby argumentów (właściwość ) Wsparcie dla zmiennej liczby argumentów (właściwość arguments ) Ma zakres leksykalny Ma zakres leksykalny

12 Funkcje (c.d.) Mogą być przypisywane do zmiennych (wcześniejszy przyklad) Mogą być przypisywane do zmiennych (wcześniejszy przyklad) Mogą być elementami tablicy Mogą być elementami tablicy var arr=[]; arr[0]=function(x){return x*x;}; arr[1]=arr[0](2); alert(arr[1]);//displays 4 Mogą mieć swoje właściwości Mogą mieć swoje właściwości var func=function(x) {alert(x);} func.ownProperty=test; Mogą być właściwościami obiektu (metody!) Mogą być właściwościami obiektu (metody!) var obj={show: function(){return -object-;}} alert(obj.show());//displays -object-

13 Funkcje (c.d.) Mogą być przekazywane jako argument Mogą być przekazywane jako argument function square(x) {return x*x;} function opOn(num,func) {return func(num);} opOn(16,square);//displays 256 Mogą być zwracane jako wartość Mogą być zwracane jako wartość function createIncrementer() { return function(x){return x+1;} } var inc = createIncrementer(); alert(inc(7));//displays 8 Muszą zwracać wartość (domyślnie jest to, z wyjątkiem wołań operatora ) Muszą zwracać wartość (domyślnie jest to undefined, z wyjątkiem wołań operatora new )

14 Metody Metoda jest funkcją wołaną z kontekstem określonego obiektu Metoda jest funkcją wołaną z kontekstem określonego obiektu Metody mogą być definiowane przez : Metody mogą być definiowane przez : Ustawienie funkcji jako właściwości obiektu Ustawienie funkcji jako właściwości obiektu myObject.method1=function(...){...} myObject.method1(...) Ex-plicite wskazany kontekst Ex-plicite wskazany kontekst myFunction.call(myObject,...) Specjalna zmienna jest dostępna wewnątrz funkcji i odnośi się do obiektu wskazanego jako kontekt (lub Obiektu Globalnego dla f. niezwiązanych) Specjalna zmienna this jest dostępna wewnątrz funkcji i odnośi się do obiektu wskazanego jako kontekt (lub Obiektu Globalnego dla f. niezwiązanych)

15 Operator new i konstruktory operator jest używany wraz z wywolaniem funkcji: operator new jest używany wraz z wywolaniem funkcji: Tworzy nowy pusty obiekt Tworzy nowy pusty obiekt Ustawia go jako dla wywołanej funkcji Ustawia go jako this dla wywołanej funkcji Ustawia go jako domyślny zwrot z funkcji (może być nadpisany) Ustawia go jako domyślny zwrot z funkcji (może być nadpisany) Jeżeli f. Jest użyta do ustawienia właściwości nowego obiektu wraz z operatoem może być uznana (i jest nazywana) konstruktorem Jeżeli f. Jest użyta do ustawienia właściwości nowego obiektu wraz z operatoem new może być uznana (i jest nazywana) konstruktorem function func() {this.prop1=val1;} var x=new func(); alert(x.prop1);//displays val1

16 Realizacja Aplikacji Internetowych Wielkie udawanie

17 OOP Emulacja metod Metody mogą być definiowane przez ustawienie właściwości na daną funkcję Metody mogą być definiowane przez ustawienie właściwości na daną funkcję myObj1.func=function(){alert(this.name);}; Połączenie obiekt-metoda jest b. słabe Połączenie obiekt-metoda jest b. słabe var myObj1={name:obj1}; var myObj2={name:obj2}; myObj1.func=function(){alert(this.name);}; myObj1.func();//displays obj1 myObj1.func.call(myObj2);//displays obj2

18 OOP Emulacja klas Konstruktory definiują sposób tworzenia obiektu (OOP klasy) Konstruktory definiują sposób tworzenia obiektu (OOP klasy) function myConstructor(value) { this.prop1=value; this.check=function(val) { if(this.prop1==val) alert(ok!); } } var myObj1=new myConstructor(obj1); myObj1.check(obj1);//displays ok! myObj1.check(obj2);//do nothing

19 OOP Emulacja klas (c.d.) Obiekty mogą współdzielić implementację swoich metod Obiekty mogą współdzielić implementację swoich metod function checkFunction(val) {if(this.prop1==val) alert(ok!); } function myConstructor(value) { this.prop1=value; this.check=checkFunction; } var myObj1=new myConstructor(obj1); myObj1.check(obj1);//displays ok!

20 OOP Emulacja klas (c.d) Konstruktor (funkcja) nie jest związany z żadnym typem Konstruktor (funkcja) nie jest związany z żadnym typem Każda funkcja może być wywołana jako konstruktor Każda funkcja może być wywołana jako konstruktor var myObj1={name:obj1}; myObj1.func=function() { alert(this.name); return {}; }; var x = new myObj1.func(); //x is empty object Obiekty nadpisują domyslny zwrot z funkcji. Typy proste już nie. Obiekty nadpisują domyslny zwrot z funkcji. Typy proste już nie.

21 OOP emulacja metod statycznych Ponieważ funkcja konstruktor faktycznie reprezentuje klasę obiektów i może być rozszerzna o własne właściwości implementacja metod i właściwości statyczny jest trywialna Ponieważ funkcja konstruktor faktycznie reprezentuje klasę obiektów i może być rozszerzna o własne właściwości implementacja metod i właściwości statyczny jest trywialna function BaseClass(name){ this.name = name; } BaseClass.staticMethod = function() { return new OtherClass(); };... var other = BaseClass.staticMethod();

22 Mamy obiekt i chcielibyśmy mieć drugi - podobny… Application.GUI.Panel;... Application.GUI.SecondPanel = Application.GUI.Panel; // this is in fact the same object!!! //What about Application.GUI.SecondPanel.Name = Second; //What is the name of the first panel? Application.GUI.Panel.Name = ???

23 Klony nadchodzą Funkcje są obiektami i można je kopiować! Application.GUI.Panel;... App.GUI.SecondPanel = {}; App.GUI.SecondPanel.Show = App.GUI.Panel.Show; App.GUI.SecondPanel.Validate = App.GUI.Panel.Validate; //and many, many more…. //what about ? App.GUI.SecondPanel.Config = App.GUI.Panel.Config;

24 Helper z ExtJS? //this copies all the stuff (including functions) //from Panel to SecondPanel Ext.apply(Application.GUI.SecondPanel, Application.GUI.Panel) // Exemplary implementation Ext.apply = function(d, e, b) { if (d && e && typeof e == "object") { for (var a in e) { d[a] = e[a] } } return d }; Issues: shallow copy prototypes

25 OOP Emulacja dziedziczenia – podejście funkcyjne function Base(name){ this.name = name; } var b = new Base("b1"); alert(b.name); //displays b1 //class Derived : Base function Derived(name,count) { Base.call(this,name); //this.baseClass=Base; this.count = count;//this.baseClass(); } var d = new Derived("d1",5); alert(d.count); //displays 5 alert(d.name); //displays d1

26 Prototypy Każda funkcja ma właściwość prototype wskazującą na obiekt (domyślnie pusty) Każdy obiekt (włączając funkcje) ma właściwość constructor. Obiekt wskazywany domyślnie przez prototype danej funkcji ma swoją właściwość constructor ustawioną na pierwotną funkcję Property constructor oraz prototype można nadpisać.

27 Prototypy (c.d.) Obiekty nie-funkcyjne mają ukrytą (niedostępną) właściwość _która pokazuje na prototyp (obiekt), który obowiązywał (wskazywało na niego w konstruktorze) w momencie tworzenia obiektu. Obiekty nie-funkcyjne mają ukrytą (niedostępną) właściwość _ prototype, która pokazuje na prototyp (obiekt), który obowiązywał (wskazywało na niego prototype w konstruktorze) w momencie tworzenia obiektu. Operator aktualizuje tworzony obiekt: Operator new aktualizuje tworzony obiekt: Ustawia wlaściwość na konstructora Ustawia wlaściwość _prototype na prototype konstructora

28 Emulacja dziedziczenia (c.d.) Łańcuch dziedziczenia po utworzeniu jest stabilny Derived.prototype=new Base1(); var d1=new Derived(...); //d1 cannot be altered to inherit //from object other than Base1...ale można go zmienić dla nowych obiektów Derived.prototype=new Base2(); var d2=new Derived(...); //d1 and d2 inherit from //different objects

29 Prototypy (c.d.) Jeżeli obiekt nie implementuje żadanej właściwości,sprawdzany jest jego prototyp, stąd: Jeżeli obiekt nie implementuje żadanej właściwości,sprawdzany jest jego prototyp, stąd: 1. Obiekt efektywnie "dziedziczy" wszystkie własciwości po swoim prototypie 2. Zmiany w prototypie są natychmiast widoczne w obiektach potomnych (równiez już utworzonych) 3. Każda wartość w prototypie może być "nadpisana" w obiekcie 4. Obiekty potomne mogą być prototypami innych obiektów, tworząc łańcuch dziedziczenia (aż do Obiektu Globalnego) Ponieważ własciwości są tworzone w locie, obiekty pochodne w momencie zapisu do dziedziczonej (z _prototype) wartości automatycznie tworzą własną kopię ("nadpisując" dziedziczoną wartość) Ponieważ własciwości są tworzone w locie, obiekty pochodne w momencie zapisu do dziedziczonej (z _prototype) wartości automatycznie tworzą własną kopię ("nadpisując" dziedziczoną wartość)

30 Prototypy (c.d.)

31 Dziedziczenie na poziomie obiektu? InheritFromObject (objectToDerrive) { var f = function() {}; f.prototype = objectToDerrive; return new f(); } App.GUI.Panel;... App.GUI.SecondPanel = InheritFromObject(App.GUI.Panel); // albo nawet ze składnią zbliżoną do f. wbudowanych Object.prototype.BegetObject = function () { var f = function() {}; f.prototype = this; return new f(); } App.GUI.Panel;... App.GUI.SecondPanel = App.GUI.Panel.BegetObject();

32 Dziedziczenie na poziomie obiektu Ale: Object jest globalny więc begetObject może być nadpisane Co będzie jak oldObject się zmieni?

33 Zmiany: App.GUI.Panel;... App.GUI.SecondPanel = App.GUI.Panel.BegetObject(); //some behaviors and attributes can be overwritten App.GUI.SecondPanel.Show = function() {}; App.GUI.SecondPanel.Title = new panel; Co będzie w momencie zmiany w App.GUI.Panel ?? Application.GUI.Panel.Validate = function() {}; //they will cause change in behavior SecondPanel in //case when the Hide function wasnt overridden

34 Emulacja dziedziczenia klas – podejscie prototypowe function Base(name){ this.name = name; } //here is an example how to create method that will be //shared across all objects of Base class Base.prototype.toString = function(){ return "name:" + this.name; }; var b = new Base("b1"); alert(b.toString());//displays name:b1 //in fact alert() calls toString() method //and Base.toString() overrides Object.toString() method

35 Emulacja dziedziczenia klas(c.d.) var b = new Base("b1");

36 Emulacja dziedziczenia klas (c.d.) //class Derived : Base function Derived(name,count) { Base.call(this,name);//Derived : base(name) this.count = count; } //Derived prototype have to be linked with Base prototype Derived.prototype = new Base(); //yes, Derived has custom toString() implementation Derived.prototype.toString = function() { return "name:"+this.name+",count:"+this.count; }; var d = new Derived("d1",5); alert(d.toString()); //displays name:b1,count:5

37 Emulacja dziedziczenia klas (c.d.) Derived.prototype = new Base(); var d = new Derived("d1",5);

38 Prototypy Nie można emulować prywatnych składowych Brak duplikacji funkcji – rozmiar obiektu nie zależy od liczby ani rozmiaru funkcji Główny problem to niekontrolowana zmiana zawertości prototypu -

39 Domknięcia Funkcje mogą być definiowane wewnątrz innych funkcji Wewnętrzne funkcje mają dostep do zmiennych i parametrów f. zewnętrznej Jesli referencja do wewnętrznej funkcji (callback) istnieje – utrzymywana jest przy życiu f. zewnętrzna function createChecker(treshold) { return function(numberToCheck) { return (numberToCheck > treshold) ? true : false; } } var checker100 = createChecker(100); alert(checker100(99));//displays false

40 Emulacja prywatnych właściwości Prywatne właściwości można zaemulować przy użyciu domknięć function Person(name){ //C# readonly this.getName=function() {return name;}; var count; this.getCount=function() {return count;}; this.setCount= function(newCount) { count=newCount;}; this.publicMethod=function(){ alert(this.name);//undefined alert(this.getName());//ok }

41 Uwaga na prototypy function Base(){ var count; this.GetCount=function() {return count;}; this.SetCount=function(newCount){count=newCount;}; } function Derived() { Base.call(this); //!!! } Derived.prototype = new Base(); var cd1=new Derived(); var cd2=new Derived(); //cd1.GetCount()==cd2.GetCount() cd1.SetCount(100); //cd1.GetCount()!=cd2.GetCount()

42 Emulacja namespaces Przestrzenie nazw mogą być emulowane jako Przestrzenie nazw mogą być emulowane jako var DATA={}; DATA.IO={}; DATA.IO.Parsers={}; var SC = DATA.IO.Parsers;//jak C# using DATA.IO.Class1=function(...){...}; DATA.IO.Class1.prototype.toString=function(){...}; var c1 = new SC.Class1(...);

43 Dziwactwa Javascript-u void nie jest typem, to prefiksowy operator zwracajacy zawsze wartość undefined Operatory bitowe i przesuniecia są wspierane ale nie ma wbudowanego typu integer. 64-bitowy typ zmiennoprzecinkowy Number jest konwerowany na 32-bitowy typ całkowity przed operacją i po niej konwertowany ponownie do Number Operator typeof zwraca string opisujący dany obiekt. typeof(new Array()) i typeof(null) zwrócą object (zamiast odpowiednio array i null )

44 Czy już wszystko jasne?

45 function getLabel() { var count = 0, concatenation = "" ['dog','cow','rabbit'].forEach(function(animal,i){ count = i+1 concatenation += animal + ' ' }) return { 'count' : count, 'animals' : concatenation }

46 Javascript wymaga średników … więc je sam sobie dodaje Gdy po nowej linii jest błedny token Gdy po nowej linii następuje ++ lub -- Gdy nowa linia następuje po continue, break, return, throw Na koncu pliku – jeśli to potrzebne ale nie dodaje Gdyby to zaowocowało pustą instrukcją Wewnątrz nagłówka instrukcji for

47 function getLabel() { var count = 0, concatenation = "" ['dog','cow','rabbit'].forEach(function(animal,i){ count = i+1 ; concatenation += animal + ' ' ; }) ; return ; { 'count' : count, 'animals' : concatenation } ; }

48 function getLabel() { var count = 0, concatenation = "" ['dog','cow','rabbit'].forEach(function(animal,i){ count = i+1 ; concatenation += animal + ' ' ; }) ; return ; { 'count' : count, 'animals' : concatenation } ; }

49 ""['dog','cow','rabbit'] return ; { 'count' : count, 'animals' : concatenation } ; Zwraca undefinefined undefined pomijane

50 ""['dog','cow','rabbit'] return ; { 'count' : count, 'animals' : concatenation } ; Możliwe rozwiazania: Dodajemy wszędzie średniki Dodajemy srednik przed linią która zaczyna się od [ ( binarnego operatora +- */ Uzywamy JSLinta/JSHinta Zwraca undefinefined undefined pomijane

51 function getLabel() { var count = 0, concatenation = "" ;['dog','cow','rabbit'].forEach(function(animal,i){ count = i+1 concatenation += animal + ' ' }) return { 'count' : count, 'animals' : concatenation }

52 Spostrzeżenie Aplikacje (również JS) maja tendencję do bycia: Bardziej skomplikowanymi większymi (i bardziej skomplikowanymi) Sa pisane w zespołach (więc są trudniejsze do ogarnięcia)

53 Typowy kod AppState = Modal;... function ShowWindow() {... if (AppState)... } Setki tysiace zmiennych i funkcji ? Problem został już odkryty – rozwiązanie nazywa się Obiektowo Zorientowane... Wszysko Co Byście Chcieli

54 W praktyce problem może być taki Application.GUI.Config.State = Modal; Application.GUI.Validate() = function () {...} Application.GUI.ShowMainWindow = function () {... if (this.Config.State) Application.Utils.DataInterface.ReadData(); } Jest hierarchia: ale nie ma kontroli nad tworzeniem (jak utworzyć podobną funkcjonalność w innym miejscu) zależności miedzy obiektami stanowią poważny problem

55 Truizmy... Jak sobie radzić z komplikacją kodu? Unikać duplikacji: Mniej kodu = mniej problemów Dzielić kod na części Mniejsze części sa łatwiejsze do zrozumienie, użycia i modyfikacji, ale muszą być niezależne! Kod powinien być jasny i łatwy do zrozumienia

56 Praktyczne wskazówki 1. Wydzielone tworzenie/reużycie obiektów: emulacja klas (clousures czy prototypy) lub dziedziczenie obiektów 2. Zależności rozwiązywane na poziomie obiektów nie odniesień do DOMa, ani hierarchii obiektów: Obiekt ma property wskazujace na inny obiekt a nie odwoluje sie do konkretnego miejsca w hierachii klas. 3. Wzorzec obserwator (event) można zaimplementowac rownież w JS 4. Testy jednostkowe, integracyjne, akceptacyjne

57 Gotowe rozwiązania Alternatywy: GWT, CofeeScript, TypeScript, DART Lekki javascipt wspierajacy różne aspekty pracy aplikacji np. JQuery Framework organizujący całą logikę aplikacji, kontrolki itd. np. ExtJS Frameworki: Angular, Knockout, Backbone Single Page Applications

58 Dokumentacja, narzędzia https://developer.mozilla.org/en/JavaScript/Refe rence international.org/publications/standards/Ecma- 262.htm JSLint, JSHint FireBug, Chrome Developer Tools, IE Inspector / WebDeveloper Fiddler

59 Realizacja Aplikacji Internetowych TESTOWANIE

60 Testowanie Testy jednostkowe Testy akceptacyjne

61 Środowisko Środowisko uruchomieniowe Framework Narzędzia dodatkowe FireUnit

62 Środowisko uruchomieniowe Przeglądarka uruchamiana ręcznie Selenium + przeglądarka Na serwerze: jsdb, rhino + env.js, WebKit

63 Framework QUnit (używany np. przez wiele plug-inów JQuery) module('calculator'); test('add numbers', function() { var calc = new Calculator(); equals(4, calc.add(2, 2)); })

64 Framework Jasmine (BDD, hierarchiczna definicja setup-ów) describe('panda',function(){ it('is happy',function(){ expect(panda).toBe('happy'); });

65 Framework Screw.Unit describe("Calculator", function() { it("should add numbers", function() { var calc = new Calculator(); expect(calc.add(2, 2)).to(equal, 4); }); }); JSSpec describe("Calculator", function() { with(this) { it("should add numbers", function() { var calc = new Calculator(); calc.add(2, 2).should(equal(4)); }); }});

66 Framework jsUnitTest new Test.Unit.Runner({ testCalculatorAdd: function() { with (this) { var calc = new Calculator(); assertEqual(4, calc.add(2, 2)); }} }); jsUnitTest + jShoulda context('Calculator', { should('add numbers', function() { with (this) { var calc = new Calculator(); assertEqual(4, calc.add(2, 2)); }}) });

67 Framework I wiele innych m.in Unittest, jsAssertUnit, YUItest, Qooxdoo, JSUnit, JSUnit, Crosscheck, Ecmaunit, Dojo Objective Harness, FireUnit, Qunit, RhinoUnit, JSpec (by Yehuda Katz)

68 Tools Smoke new Smoke.Stub(Calculator, 'add').and_return(5); Smoke.Mock(Calculator).should_receive('add').at_le ast('once').with_arguments(2, 2).and_return(5); Amok var mock = amok.mock(Calculator); mock.should_receive('add').with_args(2, Number).times(1).and_return(5); MockMe mock(Calculator).andDo(function() { SomethingThatUsesCalculator.calculate("2 + 2"); verify(Calculator.add)(2, 2); });

69 Tools qMock var mock = new Mock(); mock.expects(1).method('add').withArguments(2, 2).andReturn(5); Jack jack.expect("Calculator.add").exactly("1 time").withArguments(2, 2).mock(function() { … return sth; }) jack.create("mock", ['add', 'substract']); jack.expect("Calculator.add").exactly("1 time").whereArgument(0).isOneOf(2, 3, 4); JSMock (abandoned?) var factory = new MockControl(); var mock = factory.createMock(Calculator); mock.expects().add(2, 2).andReturn(4);

70 Istotne uwagi Izolacja od drzewa DOM i globalnych odwołań do obiektów Lokalne referencje do używanych obiektów Rozluznienie połączeń miedzy obiektami Mozliwość stosowanania wzorca obserwator (event) Stosowanie broker event (serviceBus) do komunikacji

71 Pokrycie kodu testami JSCoverage

72 Realizacja Aplikacji Internetowych JQuery

73 JQuery Silny model selekcji Wsparcie dla typowych akcji np. ustawienie obsługi zdarzenia, dodanie, usunięcie klasy stylu itd. Gotowe rozwiazania typowych problemów Rozszerzalny model - wtyczki Dużo gotowych wtyczek Testowalny

74 JQuery Problem: wyszukiwanie elementów na stronie np:for ( var (i in document.getElementsByTagName("p") ) { i.onclick = function(event) { alert("Hello!"); } } JQuery: $("p").click(function(event){ alert("Hello!!"); }

75 Jquery – Referencjonowanie

Reklamy Google