Powerful mostly unknown Javascript-Features

66
1 Powerful mostly unknown Javascript-Features 1 Freitag, 20. November 2009

description

Präsentation zum Thema "Powerful mostly unknown Javascript-Features", gehalten von Entwicklern der Softwareagentur App Aware: Sascha Hameister und Aron Homberg

Transcript of Powerful mostly unknown Javascript-Features

Page 1: Powerful mostly unknown Javascript-Features

1

Powerful mostly unknown Javascript-Features

1Freitag, 20. November 2009

Page 2: Powerful mostly unknown Javascript-Features

2

Sascha Hameister

- lebt in Berlin

- Entwickler, App Aware

- über 10 Jahre Entwicklungserfahrung

- Speaker auf Fachkonferenzen

- Autor bei O‘Reilly und Hanser-Verlag

- Fokus: Mobile, Web

2Freitag, 20. November 2009

Page 3: Powerful mostly unknown Javascript-Features

3

Aron Homberg

- lebt in München

- Entwickler, App Aware

- über 8 Jahre Entwicklungserfahrung

- Speaker auf Fachkonferenzen

- Autor bei O‘Reilly und Hanser-Verlag

- Aktiv in der OpenSource Gemeinschaft

- Fokus: Web, Datenbanken

3Freitag, 20. November 2009

Page 4: Powerful mostly unknown Javascript-Features

4

Agenda

- Daten über mehrere Aufrufe persistent halten

- Anonyme Funktionen verwenden

- Debugging von Objekten verbessern

- Standard-Verhalten nativer Funktionen ersetzen

- Aufrufhierarchien ohne Temporärvariablen

- Funktionen mit beliebiger Argumentanzahl

- Funktionalität bestehender Funktionen dynamisch erweitern

- Folgefehler durch Objektreferenzierung verhindern

- Keywords

4Freitag, 20. November 2009

Page 5: Powerful mostly unknown Javascript-Features

5

Daten über mehrere Aufrufe persistent halten

5Freitag, 20. November 2009

Page 6: Powerful mostly unknown Javascript-Features

6

Daten über mehrere Aufrufe persistent halten

- Gründe

- Persistenz im Client abbilden

- Netzwerktraffic verringern

- Serverlast verringern

6Freitag, 20. November 2009

Page 7: Powerful mostly unknown Javascript-Features

7

Client Cookies!

7Freitag, 20. November 2009

Page 8: Powerful mostly unknown Javascript-Features

8

Client Cookies

- Die Anatomie eines Cookies:

- Weitere Parameter:

- Expire date (Default: Zum Ende der Zugriffsphase)

- Path (Default: Aufrufendes Dokument)

- Domain (Default: Aktuelle Domain)

- Secure (Boolscher Parameter: Wird eine verschlüsselte Verbindung benötigt? (HTTPS)

cookieName=cookieValue

8Freitag, 20. November 2009

Page 9: Powerful mostly unknown Javascript-Features

9

Client Cookies

- Setzen eines lokalen Cookies:

- Das ganze einfach testen:

document.cookie = "dieAntwort=42";

alert(document.cookie);

// Besser (mit Firebug)

>>> console.debug(document.cookie);dieAntwort=42; ... (weitere Cookies)

9Freitag, 20. November 2009

Page 10: Powerful mostly unknown Javascript-Features

Client Cookies

- Eine schöne Funktion zum speichern:

- Persistenz bis zur nächsten WebTechCon:

function setCookie(name, value, expires, path, domain, secure) { var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "") + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : ""); document.cookie = curCookie;}

var naechsteWTC = new Date();naechsteWTC.setTime(naechsteWTC.getTime() + 365 * 24 * 60 * 60 * 1000);

setCookie("dieAntwort", 42, naechsteWTC);

10Freitag, 20. November 2009

Page 11: Powerful mostly unknown Javascript-Features

Client Cookies

- Und das ganze auslesen:

- Achtung: Cookies werden escaped gespeichert und müssen daher durch get/setCookie un/escaped werden.

function getCookie(name) { var dc = document.cookie; var prefix = name + "="; var begin = dc.indexOf("; " + prefix); if (begin == -1) { begin = dc.indexOf(prefix); if (begin != 0) return null; } else begin += 2; var end = document.cookie.indexOf(";", begin); if (end == -1) end = dc.length; return unescape(dc.substring(begin + prefix.length, end));}

11Freitag, 20. November 2009

Page 12: Powerful mostly unknown Javascript-Features

Client Cookies

- Die Persistenzschicht ist fertig:

- Seite neu laden... und das ganze nochmal:

getCookie("dieAntwort")-> 42 :-)

- Implementiert z.B. im Dojo-Framework im Namespace:dojo.cookie

console.log(getCookie("dieAntwort"));

42

12Freitag, 20. November 2009

Page 13: Powerful mostly unknown Javascript-Features

13

Anonyme Funktionen verwenden

13Freitag, 20. November 2009

Page 14: Powerful mostly unknown Javascript-Features

14

Anonyme Funktionen verwenden

- Gründe

- Implizite Codeübergabe

- Funktionalität dynamisch injecten

- Temporärcode ausführen

14Freitag, 20. November 2009

Page 15: Powerful mostly unknown Javascript-Features

15

Anonyme Funktionen!

15Freitag, 20. November 2009

Page 16: Powerful mostly unknown Javascript-Features

16

Anonyme Funktionen

- Eine anonyme Funktion kreieren:

- Einer Funktion eine anonyme Funktion übergeben:

(function () { alert("I am unnamed!");}()); // Calls the method directly

var obj = {"answer": 33};

function execOnObject(obj, funcRef) { obj.__jailCode = funcRef; obj.__jailCode(); // Einfache Variante - oder apply/call()}execOnObject(obj, function() { alert(this.answer); // -> 33});

16Freitag, 20. November 2009

Page 17: Powerful mostly unknown Javascript-Features

17

Anonyme Funktionen

- Iterative Scope-Jail-Execution (z.B. ähnlich dojo.forEach())function forEach(map, code) { for (key in map) { map[key].__jailCode = code; map[key].__jailCode(); } return map;}

var myMap = [{value: 1}, {value: 2}, {value : 3}];

myMap = forEach(myMap, function() { // This references to map iterator while // function execution this.value = this.value * 4;});

console.debug(myMap);

17Freitag, 20. November 2009

Page 18: Powerful mostly unknown Javascript-Features

18Freitag, 20. November 2009

Page 19: Powerful mostly unknown Javascript-Features

19

Debugging von Objekten verbessern

19Freitag, 20. November 2009

Page 20: Powerful mostly unknown Javascript-Features

20

Debugging von Objekten verbessern

- Gründe

- Standard-Debugging-Output von Objekten ist stets[object Object]

- Objekte werden serialisierbar (beispielsweise für den Versand zum Server)

function Person (firstName, lastName) {

}

var p = new Person("Sascha", "Hameister");alert(p); // [object Object]alert(p + " FOO"); // [object Object] FOO

20Freitag, 20. November 2009

Page 21: Powerful mostly unknown Javascript-Features

21

toString und valueOf!

21Freitag, 20. November 2009

Page 22: Powerful mostly unknown Javascript-Features

22

toString & valueOf

function Person (firstName, lastName) {

this.toString = function () { return "<Person {firstName: '" + firstName + "', lastName: '" + lastName + "'"} >" }

this.valueOf = function () { return firstName + " " + lastName; }}

var p = new Person("Sascha", "Hameister");

alert(p);// <Person {firstName: "Sascha", lastName: ”Hameister”} >

alert(p + " FOO"); // [object Object] FOO// Sascha Hameister FOO

22Freitag, 20. November 2009

Page 23: Powerful mostly unknown Javascript-Features

23

Standard-Verhalten nativer Funktionen ersetzen

23Freitag, 20. November 2009

Page 24: Powerful mostly unknown Javascript-Features

24

Standard-Verhalten nativer Funktionen ersetzen

- Gründe

- alert-, con#rm-, prompt-Funktionen mit eigener Funktionalität ersetzen und Aufrufbarkeit nativer Funktionalität sicherstellen

24Freitag, 20. November 2009

Page 25: Powerful mostly unknown Javascript-Features

25

Native function overloading!

25Freitag, 20. November 2009

Page 26: Powerful mostly unknown Javascript-Features

26

Native function overloading

var _alert = window.alert;

function alert(msg) { console.debug(msg);}

alert("FOO"); // Debugs FOO_alert("BAR") // Alerts BAR with native alert-window.

delete window.alert; // Später dazu mehr :)

alert("FOO AGAIN!");

26Freitag, 20. November 2009

Page 27: Powerful mostly unknown Javascript-Features

27

Aufrufhierarchien ohne Temporärvariablen

27Freitag, 20. November 2009

Page 28: Powerful mostly unknown Javascript-Features

28

Aufrufhierarchien ohne Temporärvariablen

- Gründe

- Mehrstu#ge Aufrufverkettungen gut leserlich implementieren (beispielsweise bei Graphenzeichnung oder Charting)

28Freitag, 20. November 2009

Page 29: Powerful mostly unknown Javascript-Features

29

Chaining!

29Freitag, 20. November 2009

Page 30: Powerful mostly unknown Javascript-Features

30

Chaining

- Verkettete Funktionsaufrufe de#nieren:

var validValues = new Array( {valid: false, value: 0}, {valid: true, value: 1}

).filter(function(ele) {

if (ele.valid) {return ele}

}).map(function(ele) {

return ele.value;

}).toString();

console.log(validValues); // -> 1

30Freitag, 20. November 2009

Page 31: Powerful mostly unknown Javascript-Features

31

Chaining

- Pro‘s:

- Sehr gut anwendbar, um temporäre Variablen zu vermeiden

- Kann bei kleinen Chains die Lesbarkeit erhöhen

- Automatisches „delete“ der - implizit nicht deklarierten - Temporärvariablen (Speicherschonend, weniger Code!)

- Con‘s:

- Achtung bei „unde#ned“ returns!

- Achtung bei zu langen Verkettungen! (Lesbarkeit)

31Freitag, 20. November 2009

Page 32: Powerful mostly unknown Javascript-Features

32

Funktionen mit beliebiger Argumentanzahl

32Freitag, 20. November 2009

Page 33: Powerful mostly unknown Javascript-Features

33

Funktionen mit beliebiger Argumentanzahl

- Gründe

- Realisierung von Funktionen wie printf

- Realisierung von Funktionen ohne benamte Parameter

33Freitag, 20. November 2009

Page 34: Powerful mostly unknown Javascript-Features

34

arguments!

34Freitag, 20. November 2009

Page 35: Powerful mostly unknown Javascript-Features

35

arguments

- Beliebige Argumentanzahlen verarbeiten:

- „arguments“ ist ein Keyword im Funktionskontext

- Es ist als Array iterierbar (arguments.length, arguments[i])

function lotOfArgs(){ console.debug(arguments);}lotOfArgs("A", "B", 3, 4, 20, true, /rg/);

-> ["A", "B", 3, 4, 20, true, /rg/]

35Freitag, 20. November 2009

Page 36: Powerful mostly unknown Javascript-Features

36

arguments

- Tracing des Aufrufers & Dynamische Rekursion:

- arguments.callee references calling function and scope

var maxThiefTry = 3;function thief() { attractOfficer();}

function attractOfficer() { maxThiefTry--; console.log("Arrest thief in... " + maxThiefTry + "times!"); if (maxThiefTry > 0) { arguments.callee(); } else { console.log("Thief arrested!") }} thief();

36Freitag, 20. November 2009

Page 37: Powerful mostly unknown Javascript-Features

37

arguments

- Drei Chancen hatte er ;-)

- Die Aufgerufene Funktion ruft den Aufrufer dynamisch auf und muss nichts über dessen Funktionsnamen etc. wissen.

- Es lassen sich so endliche und unendliche dynamische Rekursionsschleifen bzw. Ping-Pongs erstellen.

Arrest thief in... 2times!Arrest thief in... 1times!Arrest thief in... 0times!Thief arrested!

37Freitag, 20. November 2009

Page 38: Powerful mostly unknown Javascript-Features

38

Funktionalität bestehender Funktionen dynamisch erweitern

38Freitag, 20. November 2009

Page 39: Powerful mostly unknown Javascript-Features

39

Funktionalität bestehender Funktionen dynamisch erweitern

- Gründe

- Bestehende Funktionen nicht weiter aufblähen

- Mixen mehrerer Funktionalitäten zu einer neuen Funktion

39Freitag, 20. November 2009

Page 40: Powerful mostly unknown Javascript-Features

40

Delegation!

40Freitag, 20. November 2009

Page 41: Powerful mostly unknown Javascript-Features

41

Delegation

- Funktionen miteinander vereinen (Mixing)

- „func3()“ ruft „func1()“ und „func2()“ mit seinen Aufrufparametern auf!

function delegate() { var stack = arguments;

return function() { for (var i=0; i<stack.length; i++) { stack[i](arguments); } };}var func1 = function() {console.debug(arguments)};var func2 = function() {console.debug(arguments)};

func3 = delegate(func1, func2);func3("C");

41Freitag, 20. November 2009

Page 42: Powerful mostly unknown Javascript-Features

42

Folgefehler durch Objektreferenzierung verhindern

42Freitag, 20. November 2009

Page 43: Powerful mostly unknown Javascript-Features

43

Folgefehler durch Objektreferenzierung verhindern

- Standard: Mit Referenzen arbeiten:

- Achtung: Versteckte Bugs! Durch die Verwendung als Referenz wurde das Objekt Aron ebenfalls manipuliert!

- Skalare Typen werden immer kopiert, nie referenziert.

var aron = {name: "Aron Homberg"};var sascha = aron;sascha.name = "Sascha Hameister";

console.debug(aron);

-> aron.name -> „Sascha Hameister“

43Freitag, 20. November 2009

Page 44: Powerful mostly unknown Javascript-Features

44

Objekte klonen!

44Freitag, 20. November 2009

Page 45: Powerful mostly unknown Javascript-Features

Objekte klonen

- Lösung: Objekte und ihre Attribute (1st-Level) klonen!

- Diese Funktion klont lediglich die erste Attribut-Ebene eines Objekts. In tieferen Ebenen blieben Referenzen erhalten.

function clone(props) { var tobj = {}; for(var x in props){ tobj[x] = props[x]; } return tobj;}var aron = {name: "Aron Homberg"};var sascha = clone(aron);sascha.name = "Sascha Hameister";

console.debug(aron);

-> aron.name -> „Aron Homberg“ // Bleibt unverändert!

45Freitag, 20. November 2009

Page 46: Powerful mostly unknown Javascript-Features

46

Keywords

46Freitag, 20. November 2009

Page 47: Powerful mostly unknown Javascript-Features

47

Keywords

- instanceof

- typeof

- with

- delete

- in

- continue

- new

47Freitag, 20. November 2009

Page 48: Powerful mostly unknown Javascript-Features

48

Keyword: instanceof

48Freitag, 20. November 2009

Page 49: Powerful mostly unknown Javascript-Features

49

Keyword: instanceof

var example = 'FOO';alert(example instanceof String); // false

var example = new String('FOO');alert(example instanceof String); // true

- Gibt true zurück, wenn das Objekt die Instanz einer gegebenen Klasse ist.

49Freitag, 20. November 2009

Page 50: Powerful mostly unknown Javascript-Features

50

Keyword: typeof

50Freitag, 20. November 2009

Page 51: Powerful mostly unknown Javascript-Features

51

Keyword: typeof

var example = 'FOO';alert(typeof example); // string

var example = 10;alert(typeof example); // number

var example = true;alert(typeof example); // boolean

var example = /foo/igalert(typeof example); // object

var example = [];alert(typeof example); // object

var example = {};alert(typeof example); // object

51Freitag, 20. November 2009

Page 52: Powerful mostly unknown Javascript-Features

52

Keyword: with

52Freitag, 20. November 2009

Page 53: Powerful mostly unknown Javascript-Features

53

Keyword: with

with (document.getElementById('example')) {innerHTML = 'HTML INHALT';style.color = '#123456';style.height = '20px';

}

53Freitag, 20. November 2009

Page 54: Powerful mostly unknown Javascript-Features

54

Keyword: delete

54Freitag, 20. November 2009

Page 55: Powerful mostly unknown Javascript-Features

55

Keyword: delete

- Per delete können Zuweisungen aller Art hart gelöscht werden:

Mit „delete“ lässt sich Speicher freiräumen. Temporärvariablen bei Iterationen sollten so immer „Garbage collected“ werden.

var object = {attribute1 : 'value1',attribute2 : 'value2'

};

delete object.attribute1;

55Freitag, 20. November 2009

Page 56: Powerful mostly unknown Javascript-Features

56

Keyword: delete

var anArray = ['foo', 'bar'];

delete anArray[1];

for (var i = 0; i < anArray.length; i++) {console.log(anArray[i]); // foo, undefined

}

- Aufpassen bei Arrays oder Iterationen!

Es wird hart gelöscht. Eine Änderung der Indizes oder des length-Attributes des Arrays erfolgt nicht!

56Freitag, 20. November 2009

Page 57: Powerful mostly unknown Javascript-Features

57

Keyword: delete

- ACHTUNG: delete() löscht je nach Implementation (Javascript-VM / Interpreter) hart die Referenz aus dem Memory.

- Bei Zugriff auf einen so gelöschten Wert können dadurch kritische Interpreter / VM-Runtime Execution Fehler auftreten.

57Freitag, 20. November 2009

Page 58: Powerful mostly unknown Javascript-Features

58

Keyword: in

58Freitag, 20. November 2009

Page 59: Powerful mostly unknown Javascript-Features

59

Keyword: in

var object = {attribute1 : 'value1',attribute2 : 'value2'

};

'attribute1' in object // TRUE

var object = {attribute1 : 'value1',attribute2 : 'value2'

};

var idx;for (idx in object) {

alert(object[idx]); // two alerts… value1, value2}

59Freitag, 20. November 2009

Page 60: Powerful mostly unknown Javascript-Features

60

Keyword: in (Prototypes!)

Object.prototype.example = function () {};

var object = {attribute1 : 'value1',attribute2 : 'value2'

};

var idx;for (idx in object) {

alert(object[idx]); // Was erwarten Sie?}

value1value2function () {}

60Freitag, 20. November 2009

Page 61: Powerful mostly unknown Javascript-Features

61

Keyword: in (Prototypes!)

- Bei der Nutzung von in bei jedem Cycle Plausibilitätsprüfung des aktuellen Typs

Object.prototype.example = function () {};

var object = {attribute1 : 'value1',attribute2 : 'value2'

};

var currentObject;var idx;for (idx in object) {

currentObject = object[idx];if (typeof currentObject === 'string') {

alert(object[idx]); // two alerts… value1, value2}

}

61Freitag, 20. November 2009

Page 62: Powerful mostly unknown Javascript-Features

62

Keyword: continue

62Freitag, 20. November 2009

Page 63: Powerful mostly unknown Javascript-Features

63

Keyword: continue

outerLabel: for (var i = 0; i < 5; i++) {innerLabel: for (var j = 0; j < 5; j++) {

if (j == 2) {continue outerLabel;

} }}

63Freitag, 20. November 2009

Page 64: Powerful mostly unknown Javascript-Features

64

Keyword: new

64Freitag, 20. November 2009

Page 65: Powerful mostly unknown Javascript-Features

65

Keyword: new

function MyClass () {}

var foo = new MyClass();

var bar = MyClass();

// Unterschied?

function MyClass () { if (!(this instanceof MyClass)) { throw 'You tried to instantiate MyClass without new.'; }}

65Freitag, 20. November 2009

Page 66: Powerful mostly unknown Javascript-Features

66

Powerful known Javascript-Features!

Vielen Dank! :-)

66Freitag, 20. November 2009