Successfully reported this slideshow.

Powerful mostly unknown Javascript-Features

1,118 views

Published on

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

Published in: Education, Technology
  • Be the first to comment

Powerful mostly unknown Javascript-Features

  1. 1. Powerful mostly unknown Javascript-Features 1 Freitag, 20. November 2009 1
  2. 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 2 Freitag, 20. November 2009 2
  3. 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 3 Freitag, 20. November 2009 3
  4. 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 4 Freitag, 20. November 2009 4
  5. 5. Daten über mehrere Aufrufe persistent halten 5 Freitag, 20. November 2009 5
  6. 6. Daten über mehrere Aufrufe persistent halten - Gründe - Persistenz im Client abbilden - Netzwerktraffic verringern - Serverlast verringern 6 Freitag, 20. November 2009 6
  7. 7. Client Cookies! 7 Freitag, 20. November 2009 7
  8. 8. Client Cookies - Die Anatomie eines Cookies: cookieName=cookieValue - 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) 8 Freitag, 20. November 2009 8
  9. 9. Client Cookies - Setzen eines lokalen Cookies: document.cookie = "dieAntwort=42"; - Das ganze einfach testen: alert(document.cookie); // Besser (mit Firebug) ⋮ >>> console.debug(document.cookie); dieAntwort=42; ... (weitere Cookies) 9 Freitag, 20. November 2009 9
  10. 10. Client Cookies - Eine schöne Funktion zum speichern: 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; } - Persistenz bis zur nächsten WebTechCon: var naechsteWTC = new Date(); naechsteWTC.setTime(naechsteWTC.getTime() + 365 * 24 * 60 * 60 * 1000); setCookie("dieAntwort", 42, naechsteWTC); Freitag, 20. November 2009 10
  11. 11. Client Cookies - Und das ganze auslesen: 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)); } - Achtung: Cookies werden escaped gespeichert und müssen daher durch get/setCookie un/escaped werden. Freitag, 20. November 2009 11
  12. 12. Client Cookies - Die Persistenzschicht ist fertig: console.log(getCookie("dieAntwort")); ⋮ 42 - Seite neu laden... und das ganze nochmal: getCookie("dieAntwort") -> 42 :-) - Implementiert z.B. im Dojo-Framework im Namespace: dojo.cookie Freitag, 20. November 2009 12
  13. 13. Anonyme Funktionen verwenden 13 Freitag, 20. November 2009 13
  14. 14. Anonyme Funktionen verwenden - Gründe - Implizite Codeübergabe - Funktionalität dynamisch injecten - Temporärcode ausführen 14 Freitag, 20. November 2009 14
  15. 15. Anonyme Funktionen! 15 Freitag, 20. November 2009 15
  16. 16. Anonyme Funktionen - Eine anonyme Funktion kreieren: (function () { alert("I am unnamed!"); }()); // Calls the method directly - Einer Funktion eine anonyme Funktion übergeben: 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 16 }); Freitag, 20. November 2009 16
  17. 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); 17 Freitag, 20. November 2009 17
  18. 18. Freitag, 20. November 2009 18
  19. 19. Debugging von Objekten verbessern 19 Freitag, 20. November 2009 19
  20. 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 20 Freitag, 20. November 2009 20
  21. 21. toString und valueOf! 21 Freitag, 20. November 2009 21
  22. 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 22 Freitag, 20. November 2009 22
  23. 23. Standard-Verhalten nativer Funktionen ersetzen 23 Freitag, 20. November 2009 23
  24. 24. Standard-Verhalten nativer Funktionen ersetzen - Gründe - alert-, con rm-, prompt-Funktionen mit eigener Funktionalität ersetzen und Aufrufbarkeit nativer Funktionalität sicherstellen 24 Freitag, 20. November 2009 24
  25. 25. Native function overloading! 25 Freitag, 20. November 2009 25
  26. 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!"); 26 Freitag, 20. November 2009 26
  27. 27. Aufrufhierarchien ohne Temporärvariablen 27 Freitag, 20. November 2009 27
  28. 28. Aufrufhierarchien ohne Temporärvariablen - Gründe - Mehrstu ge Aufrufverkettungen gut leserlich implementieren (beispielsweise bei Graphenzeichnung oder Charting) 28 Freitag, 20. November 2009 28
  29. 29. Chaining! 29 Freitag, 20. November 2009 29
  30. 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 30 Freitag, 20. November 2009 30
  31. 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) 31 Freitag, 20. November 2009 31
  32. 32. Funktionen mit beliebiger Argumentanzahl 32 Freitag, 20. November 2009 32
  33. 33. Funktionen mit beliebiger Argumentanzahl - Gründe - Realisierung von Funktionen wie printf - Realisierung von Funktionen ohne benamte Parameter 33 Freitag, 20. November 2009 33
  34. 34. arguments! 34 Freitag, 20. November 2009 34
  35. 35. arguments - Beliebige Argumentanzahlen verarbeiten: function lotOfArgs() { console.debug(arguments); } lotOfArgs("A", "B", 3, 4, 20, true, /rg/); ⋮ -> ["A", "B", 3, 4, 20, true, /rg/] - „arguments“ ist ein Keyword im Funktionskontext - Es ist als Array iterierbar (arguments.length, arguments[i]) 35 Freitag, 20. November 2009 35
  36. 36. arguments - Tracing des Aufrufers & Dynamische Rekursion: 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(); - arguments.callee references calling function and scope36 Freitag, 20. November 2009 36
  37. 37. arguments - Drei Chancen hatte er ;-) Arrest thief in... 2times! Arrest thief in... 1times! Arrest thief in... 0times! Thief arrested! - 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. 37 Freitag, 20. November 2009 37
  38. 38. Funktionalität bestehender Funktionen dynamisch erweitern 38 Freitag, 20. November 2009 38
  39. 39. Funktionalität bestehender Funktionen dynamisch erweitern - Gründe - Bestehende Funktionen nicht weiter aufblähen - Mixen mehrerer Funktionalitäten zu einer neuen Funktion 39 Freitag, 20. November 2009 39
  40. 40. Delegation! 40 Freitag, 20. November 2009 40
  41. 41. Delegation - Funktionen miteinander vereinen (Mixing) 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"); - „func3()“ ruft „func1()“ und „func2()“ mit seinen Aufrufparametern auf! 41 Freitag, 20. November 2009 41
  42. 42. Folgefehler durch Objektreferenzierung verhindern 42 Freitag, 20. November 2009 42
  43. 43. Folgefehler durch Objektreferenzierung verhindern - Standard: Mit Referenzen arbeiten: var aron = {name: "Aron Homberg"}; var sascha = aron; sascha.name = "Sascha Hameister"; console.debug(aron); -> aron.name -> „Sascha Hameister“ - Achtung: Versteckte Bugs! Durch die Verwendung als Referenz wurde das Objekt Aron ebenfalls manipuliert! - Skalare Typen werden immer kopiert, nie referenziert. 43 Freitag, 20. November 2009 43
  44. 44. Objekte klonen! 44 Freitag, 20. November 2009 44
  45. 45. Objekte klonen - Lösung: Objekte und ihre Attribute (1st-Level) klonen! 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! - Diese Funktion klont lediglich die erste Attribut-Ebene eines Objekts. In tieferen Ebenen blieben Referenzen erhalten. Freitag, 20. November 2009 45
  46. 46. Keywords 46 Freitag, 20. November 2009 46
  47. 47. Keywords - instanceof - typeof - with - delete - in - continue - new 47 Freitag, 20. November 2009 47
  48. 48. Keyword: instanceof 48 Freitag, 20. November 2009 48
  49. 49. Keyword: instanceof - Gibt true zurück, wenn das Objekt die Instanz einer gegebenen Klasse ist. var example = 'FOO'; alert(example instanceof String); // false var example = new String('FOO'); alert(example instanceof String); // true 49 Freitag, 20. November 2009 49
  50. 50. Keyword: typeof 50 Freitag, 20. November 2009 50
  51. 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/ig alert(typeof example); // object var example = []; alert(typeof example); // object var example = {}; alert(typeof example); // object 51 Freitag, 20. November 2009 51
  52. 52. Keyword: with 52 Freitag, 20. November 2009 52
  53. 53. Keyword: with with (document.getElementById('example')) { innerHTML = 'HTML INHALT'; style.color = '#123456'; style.height = '20px'; } 53 Freitag, 20. November 2009 53
  54. 54. Keyword: delete 54 Freitag, 20. November 2009 54
  55. 55. Keyword: delete - Per delete können Zuweisungen aller Art hart gelöscht werden: var object = { attribute1 : 'value1', attribute2 : 'value2' }; ⋮ delete object.attribute1; Mit „delete“ lässt sich Speicher freiräumen. Temporärvariablen bei Iterationen sollten so immer „Garbage collected“ werden. 55 Freitag, 20. November 2009 55
  56. 56. Keyword: delete - Aufpassen bei Arrays oder Iterationen! var anArray = ['foo', 'bar']; delete anArray[1]; for (var i = 0; i < anArray.length; i++) { console.log(anArray[i]); // foo, undefined } Es wird hart gelöscht. Eine Änderung der Indizes oder des length- Attributes des Arrays erfolgt nicht! 56 Freitag, 20. November 2009 56
  57. 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. 57 Freitag, 20. November 2009 57
  58. 58. Keyword: in 58 Freitag, 20. November 2009 58
  59. 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 } 59 Freitag, 20. November 2009 59
  60. 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? } value1 value2 function () {} 60 Freitag, 20. November 2009 60
  61. 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 } } 61 Freitag, 20. November 2009 61
  62. 62. Keyword: continue 62 Freitag, 20. November 2009 62
  63. 63. Keyword: continue outerLabel: for (var i = 0; i < 5; i++) { innerLabel: for (var j = 0; j < 5; j++) { if (j == 2) { continue outerLabel; } } } 63 Freitag, 20. November 2009 63
  64. 64. Keyword: new 64 Freitag, 20. November 2009 64
  65. 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.'; } } 65 Freitag, 20. November 2009 65
  66. 66. Powerful known Javascript- Features! Vielen Dank! :-) 66 Freitag, 20. November 2009 66

×