Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

50

Transcript of Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Page 1: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM
Page 2: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Organizacja ucząca się Javascript - wprowadzenie

07-03-2014

Wiktor Zychla

Page 3: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Agenda

• Wprowadzenie

• Funkcje/domknięcia

• Obiekty • this

• Dziedziczenie

• Enkapsulacja

• Perspektywy

• Egzamin

Page 4: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Wprowadzenie - historia

• 1995 – Brendan Eich dla Netscape

• 1996 – ECMA 262

• 1996 – Microsoft wprowadza do IE3

• 1998 – ES2

• 1999 – ES3

• 2009 – ES5

• 2011 – ES5.1

• 201? – ES6

http://kangax.github.io/es5-compat-table/

Page 5: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Host

Kod Javascript wykonuje się w ramach hosta,

typowo jest to przeglądarka. Do obiektu hosta jest

dostęp jawny:

window.x = 3;

x = 3; // równoważne, zmienna globalna

Zmienne lokalne

var x = 3;

Page 6: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Host Host daje dostęp do struktury dokumentu który jest aktualnie załadowany

(DOM). Javascript może tę strukturę dynamicznie modyfikować.

Obecnie większość przeglądarek ma silniki kompilujące Javascript do

kodu natywnego przed wykonaniem.

Javascript nie tylko jest więc coraz bardziej zgodny, ale też jest bardzo

szybki.

http://www.wiktorzychla.com/2014/02/animated-javascript-julia-

fractals.html

http://jsdosbox.appspot.com/

Page 7: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Funkcje

Funkcje nazwane/nienazwane function() {}

function f() {}

Page 8: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Funkcje

Funkcje zdefiniowane w compile-time vs run-time

f();

function f() {}

vs f();

var f = function() {}

Page 9: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Zasięg widoczności zmiennych

Globalny

var x = 5;

var f = function() {

console.log('x='+x);

}

f();

Page 10: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Zasięg widoczności zmiennych

Lokalny

var x = 5;

var f = function() {

var x = 1;

console.log('x='+x);

}

f();

Page 11: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Zasięg widoczności zmiennych

Uwaga na „hoisting”

var x = 5;

var f = function() {

console.log('x='+x);

var x = 3;

}

f();

Page 12: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Zasięg widoczności zmiennych

Hoisting polega na tym, że w zasięgu bloku

wszystkie zmienne są „wirtualnie” zdefiniowane na

początku bloku.

var x = 5;

var f = function() {

var x;

console.log('x='+x);

x = 3;

}

f();

Page 13: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Funkcje

Javascript jest językiem funkcyjnym – funkcje mogą

być przekazywane do funkcji jako argumenty i

zwracane jako wyniki.

Page 14: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Funkcje

Funkcja przekazywana jako argument

function f(g) {

return g();

}

f(function() { return 1; });

Page 15: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Funkcje

Funkcja zwracana jako wartość

function f() {

function g() {

return 1;

}

return g;

}

f()();

Page 16: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Domknięcia

Domknięcie to „ukryty” parametr funkcji, który łapie

wszystkie zmienne z których funkcja korzysta, ale

nie definiuje ich.

function sum1(x,y) {

return x + y;

}

console.log( sum1(2,3) );

Page 17: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Domknięcia To samo z domknięciem

function sum2(x) {

function helper(y) {

return x + y;

}

return helper;

}

console.log(sum2(2)(3));

Kontekst funkcji wewnętrznej helper domyka

zmienną x.

Page 18: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Domknięcia

Ekstremalnie: function sum3(x) {

var _s = x;

function helper(y) {

_s += y;

return helper;

}

helper.toString = function() { return _s; }

return helper;

}

var result = sum3(1)(2)(3)(4); // dowolna liczba parametrów

console.log(result);

Page 19: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Domknięcia

Kontekst jest obiektem, więc może być modyfikowany: function f(person) {

function g(message) {

console.log( 'message [' + message + '] to ' +

person.name );

}

return g;

}

var p = { name : 'jan' }

var messenger = f(p);

messenger('witaj!'); // witaj to jan

p.name = 'tomasz';

messenger('ukłony'); // ukłony to tomasz

Page 20: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Domknięcia Co czasem bywa nieoczekiwane function createFs(n) { // tworzy tablicę n funkcji

var fs = []; // i-ta funkcja z tablicy ma zwrócić i

var i;

for ( i=0; i<n; i++ ) {

fs[i] = function() {

return i;

}; // <- funkcja się nie wykonuje, jest obiekt kontekstu do którego trafia i

// ale wartość i się zmienia zanim funkcje zaczną się wykonywać

};

return fs;

}

var myfs = createFs(10);

console.log( myfs[0]() ); // zerowa funkcja miała zwrócić 0

console.log( myfs[2]() ); // druga miała zwrócić 2

console.log( myfs[7]() );

// output : 10,10,10, oops, wszystkie zwracają 10!

Page 21: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Domknięcia Ale nietrudno to naprawić function createFs(n) {

var fs = [];

var i;

for ( i=0; i<n; i++ ) {

fs[i] = function(x) {

return function() {

return x;

};

}(i); // <- funkcja od razu się wykonuje i za każdym razem tworzy nowy kontekst

// (n różnych kontekstów vs jeden i ten sam)

};

return fs;

}

var myfs = createFs(10);

console.log( myfs[0]() );

console.log( myfs[2]() );

console.log( myfs[7]() );

// output: 0, 2, 7

Page 22: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Obiekty Najprościej

var p = {}; // albo new Object();

p.name = 'jan';

console.log(p.name);

Notacja . vs []

var p = {}

p.name = 'jan';

p['name'] = 'tomasz';

console.log(p.name);

Notacja [] jest bardziej ogólna bo parametr może być wyrażeniem

var p = {}

p.name = 'jan';

p['na'+'me'] = 'tomasz';

console.log(p.name);

Page 23: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Obiekty Składnia literalna (literal syntax)

var p = {

name : 'jan',

age : 15

}

console.log( p.name );

Drzewa obiektów (obiekty kompozytowe)

var p = {

name : 'jan',

address : {

city : 'wrocław'

}

}

console.log( p.address.city );

Page 24: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Obiekty - dygresja Iteracja po tablicy vs iteracja po polach obiektu

var a = [];

a.push(1);

a.push(2);

for ( var i=0; i<a.length; i++ )

console.log( a[i] );

vs

var p = {

name : 'jan',

age : 17

}

for ( var key in p ) {

console.log( key + ' : ' + p[key] );

}

Page 25: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Obiekty - dygresja Parametry są przekazywane przez wartość

function f( x ) {

x = 123;

}

var a = 1;

f(a);

console.log(a); // 1. funkcja nie modyfikuje wartości

czyli w przypadku obiektów – przez wartość referencji

function f( x ) {

x.age = 123;

}

var p = { age : 1 };

f(p);

console.log(p.age);} // 123.

// referencja nie jest modyfikowana ale pole za nią tak

Page 26: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

This v.1 W funkcjach instancji obiektu this odnosi się do instancji obiektu …

var person = {

name : 'jan',

say : function() {

return this.name;

}

}

console.log( person.say() );

Page 27: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

This v.2 W funkcjach spoza obiektów this odnosi się domyślnie do hosta (window)

var name = 'jan';

say = function() {

return this.name;

}

console.log( say() );

Page 28: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

This v.2 … ale można wywołać funkcję nie wprost, tylko przez call, które jako pierwszy

parametr przyjmuje obiekt dowiązywany to this wewnątrz funkcji

p = { name : 'jan' };

say = function() {

return this.name;

}

console.log( say.call( p ) );

Page 29: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

This v.2 - dygresja Wywołania przez call a apply

p = { name : 'jan' };

say = function(m1, m2) {

return this.name + ' has ' + m1 + ' and ' + m2;

}

console.log( say.call( p, 'a', 'b' ) ); // lista parametrów

p = { name : 'jan' };

say = function(m1, m2) {

return this.name + ' has ' + m1 + ' and ' + m2;

}

console.log( say.apply( p, ['a', 'b'] ) ); // tablica parametrów

Page 30: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie W Javascript nie ma klas.

Tyle że w języku obiektowym nie potrzeba klas – potrzeba obiektów.

Nowe obiekty tworzy się albo ad-hoc albo klonując istniejące „wzorcowe” obiekty

– mówimy o nich prototypy.

var personProto = { // prototyp

name : 'jan',

say : function() {

return this.name;

}

}

var p1 = Object.create( personProto ); // klonowanie prototypu

p1.name = 'tomasz';

var p2 = Object.create( personProto );

p2.name = 'janusz';

console.log( p1.say() );

console.log( p2.say() );

Page 31: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Nieoczekiwany problem - obiekt kompozytowy w prototypie

var personProto = {

name : 'jan',

address : {

city : 'wrocław'

},

say : function() {

return this.address.city;

}

}

var p1 = Object.create( personProto );

p1.address.city = 'kraków';

var p2 = Object.create( personProto );

p2.address.city = 'łódź';

console.log( p1.say() );

console.log( p2.say() );

// output : łódź, łódź zamiast kraków, łódź

Jak to obejść?

Page 32: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Można tak

var personProto = {

name : 'jan',

address : {

city : 'wrocław'

},

say : function() {

return this.address.city;

}

}

var p1 = Object.create( personProto );

p1.address = { city : 'kraków' }; // za każdym razem twórz nowy podobiekt

var p2 = Object.create( personProto );

p2.address = { city : 'łódź' };

console.log( p1.say() );

console.log( p2.say() );

Ale to nie wygląda dobrze, bo trzeba o tym pamiętać.

Page 33: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Rozwiązaniem jest taki prototyp, który klonuje się dedykowaną metodą tworzącą (factory function):

var person = {

create : function(name, city) {

var _ = Object.create( this );

_.name = name;

_.address = {

city : city

};

return _;

},

say : function() {

return this.address.city;

}

}

var p1 = person.create( 'jan', 'kraków' );

var p2 = person.create( 'tomasz', 'łódź' );

console.log( p1.say() );

console.log( p2.say() );

Page 34: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie W ten sposób można zaimplementować dziedziczenie var person = {

create : function(name, city) {

var _ = Object.create( this );

_.name = name;

_.address = {

city : city

};

return _;

},

say : function() {

return this.address.city;

}

}

var pupil = {

create : function(name, city, school) {

var _ = person.create.call( this, name, city );

_.school = school;

return _;

},

say : function() {

var _ = person.say.call( this );

return _ + ' ' + this.school;

}

}

var p1 = person.create( 'jan', 'kraków' );

var p2 = pupil.create( 'tomasz', 'łódź', 'sp1' );

console.log( p1.say() );

console.log( p2.say() );

Page 35: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Wszystko pięknie tylko co się stanie jeśli pupil nie ma dostarczonej implementacji metody say, a

zamiast tego oczekujemy że zawoła się metoda z prototypu (mówiąc żargonem obiektowym: z klasy bazowej)?

Zakomentowanie metody say w pupil pokazuje że całość przestaje działać. pupil jako prototyp nie

ma metody say!

Można próbować to ratować:

var person = {

create : function(name, city) {

var _ = Object.create( person );

_.name = name;

_.address = {

city : city

};

return _;

},

say : function() {

return this.address.city;

}

}

ale wtedy przestaje działać przeciążanie metody say w pupil

Page 36: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Prawdziwym źródłem problemu jest to, że pupil nie powstał z person w taki sam sposób w jaki

konstruujemy pozostałe obiekty – przez sklonowanie.

Zamiast tego zarówno pupil jak i person powstały w sposób literalny.

Niestety, dostęp do prototypu obiektu nie jest jawny (jeśli się da to nie jest to standard). Nie można więc

tego łatwo naprawić.

Jedyny uniwersalny sposób to wprowadzić nieładną funkcję do klonowania prototypów i rozszerzania ich

o dodatkowe właściwości:

var extend = function(base, extension) {

// klonuj prototyp

var object = Object.create(base);

// wkopiuj mu rozszerzone właściwości

var hasOwnProperty = Object.hasOwnProperty;

for (var property in extension)

if (hasOwnProperty.call(extension, property) ||

typeof object[property] === "undefined")

object[property] = extension[property];

return object;

};

Page 37: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie W takim środowisku rozszerzanie obiektów (dziedziczenie) działa tak jak powinno:

var pupil = extend( person, {

create : function(name, city, school) {

var _ = person.create.call( this, name, city );

_.school = school;

return _;

}

//,

//say : function() {

// var _ = person.say.call( this );

// return _ + ' ' + this.school;

//}

} );

Metodę say można zakomentować (i wtedy działa implementacja z prototypu, z person) albo

odkomentować (i wtedy działa implementacja z pupil).

Wiele frameworków mimo to podąża tą ścieżką.

Page 38: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Ale dziedziczenie można osiągnąć inaczej, przez funkcje konstruktorowe (constructor function)

function Foo() {

...

}

var f = new Foo();

to jest równoważne

var f = new Object();

f.[[prototype]] = Foo.prototype;

f.Foo(); // binduje this

gdzie

Foo.prototype – to prototyp który funkcja konstruktorowa przypina jako prototyp do nowo tworzonego

obiektu. W przeciwieństwie do poprzedniego podejścia, prototyp ten jest jawny i można go modyfikować.

Page 39: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Mamy wtedy …

function Person(name, city) {

this.name = name;

this.address = {

city : city

};

this.say = function() {

return this.name + ' ' + this.address.city;

};

}

var p1 = new Person('jan', 'wrocław');

console.log( p1.say() );

object Prototype1

Person.prototype

p1

name = name

say = function

p2

name = name

say = function

Page 40: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie … albo (uwaga!)

function Person(name, city) {

this.name = name;

this.address = {

city : city

};

}

Person.prototype.say = function() {

return this.name + ' ' + this.address.city;

};

var p1 = new Person('jan', 'wrocław');

console.log( p1.say() );

object Prototype2

Person.prototype

say = function

p2

name = name

p1

name = name

Page 41: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Dziedziczenie jest łatwiejsze:

function Person(name, city) {

this.name = name;

this.address = {

city : city

};

}

Person.prototype.say = function() {

return this.name + ' ' + this.address.city;

};

function Pupil(name, city, school) {

Person.call( this, name, city );

this.school = school;

}

var p1 = new Person('jan', 'wrocław');

console.log( p1.say() );

var p2 = new Pupil('tomasz', 'łódź', 'sp1');

console.log( p2.say() ); // problem!

Oops, nie działa say w pupil!

Page 42: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Tym razem obrona jest łatwa:

function Person(name, city) {

this.name = name;

this.address = {

city : city

};

}

Person.prototype.say = function() {

return this.name + ' ' + this.address.city;

};

function Pupil(name, city, school) {

Person.call( this, name, city );

this.school = school;

}

Pupil.prototype = new Person();

// lub Pupil.prototype = Person.prototype jeżeli metody są ustawiane tylko w prototypie

var p1 = new Person('jan', 'wrocław');

console.log( p1.say() );

var p2 = new Pupil('tomasz', 'łódź', 'sp1');

console.log( p2.say() );

class Jav ascript

Person.prototype Pupil.prototype p2

Page 43: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziedziczenie Wywołanie metody z klasy bazowej jest łatwe:

function Person(name, city) {

this.name = name;

this.address = {

city : city

};

}

Person.prototype.say = function() {

return this.name + ' ' + this.address.city;

};

function Pupil(name, city, school) {

Person.call( this, name, city );

this.school = school;

}

Pupil.prototype = new Person();

Pupil.prototype.say = function() {

var _ = Person.prototype.say.call( this );

return _ + ' ' + this.school;

}

var p1 = new Person('jan', 'wrocław');

console.log( p1.say() );

var p2 = new Pupil('tomasz', 'łódź', 'sp1');

console.log( p2.say() );

Page 44: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Enkapsulacja Składowe prywatne w klasie – przez domknięcie

function Person(name) {

var _private = 5;

this.name = name;

this.say = function() {

return this.name + ' ' + _private;

}

}

var p = new Person('jan');

console.log( p.say() );

console.log( p._private ); // niedostępne

Page 45: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Enkapsulacja Moduły – zagnieżdżone obiekty

function CreateNamespace( moduleName ) {

var parent = window;

var seg = moduleName.split('.');

for ( var part=0; part<seg.length; part++ )

{

var segName = seg[part];

if ( typeof parent[segName] === 'undefined' )

parent[segName] = {};

parent = parent[segName];

}

}

CreateNamespace( 'Vulcan.Architekt.CentralneSlowniki' );

Page 46: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Enkapsulacja I teraz

Vulcan.Architekt.CentralneSlowniki = {

// klasa publiczna

Person : function(name) {

this.name = name;

this.say = function() {

return name;

}

}

}

var p = new Vulcan.Architekt.CentralneSlowniki.Person('jan');

console.log( p.say() );

Page 47: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Enkapsulacja Można nawet mieć w module prywatną klasę:

Vulcan.Architekt.CentralneSlowniki = (function() {

// klasa prywatna bo w domknięciu funkcji która się od razu wykonuje

function Private() {

this.helper = function(s) {

return s + ' from helper!';

}

}

return {

// klasa publiczna

Person : function(name) {

this.name = name;

this.say = function() {

var _pr = new Private();

return _pr.helper(this.name);

}

}

}

}());

var p = new Vulcan.Architekt.CentralneSlowniki.Person('jan');

console.log( p.say() );

var q = new Vulcan.Architekt.CentralneSlowniki.Private(); // nie

Page 48: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

ECMAScript 6 Wiele fajnych nowych rzeczy, m.in. lambda wyrażenia:

var a = [ "Wlazł kotek na płotek",

"I mruga"

];

// po staremu

var a2 = a.map(function(s){ return s.length });

// po nowemu

var a3 = a.map( s => s.length );

Page 49: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Podsumowanie

Javascript to nowoczesny i wydajny język tworzenia

aplikacji.

Jedynym minusem jest uboga biblioteka

standardowa, co oznacza, że trzeba wspierać się

zewnętrznymi frameworkami.

Page 50: Slajd 1wzychla/files/Javascript.pdfTitle: Slajd 1 Author: Olam Created Date: 2/2/2015 10:53:18 PM

Dziękuję za uwagę