Advanced Object-Oriented JavaScript

11,244 views

Published on

Presentation at the Dynamic World Conference DLW 08 Europe

Published in: Business, Technology

Advanced Object-Oriented JavaScript

  1. 1. Andreas Ecker | 1&1 Internet AG Advanced Object-Oriented JavaScript
  2. 2. These keywords belong too ... throws abstract extends package transient boolean final private protected volatile byte float char implements public class import short const int static double interface super enum long synchronized export native Andreas Ecker | 1&1 Internet AG page 2
  3. 3. ... JavaScript ! ECMAScript 3 / JavaScript 1.5 Standard spezified in 1999 Supported by all common browsers Many keywords reserved, but not used ECMAScript 4 / JavaScript 2.0 Many new language features Not expected any time soon Andreas Ecker | 1&1 Internet AG page 3
  4. 4. Data Types Primitive Types Reference Types Andreas Ecker | 1&1 Internet AG page 4
  5. 5. Primitive Types Boolean true, false Number 1, 3.141, -1.602e-19 String quot;Joequot; null null undefined undefined Andreas Ecker | 1&1 Internet AG page 5
  6. 6. Reference Types Date new Date(1211623944453); Error new Error(quot;Oops!quot;); RegExp /^web.*$/i; Array [ quot;applequot;, quot;bananaquot; ] Function function(x) {return x*x} Andreas Ecker | 1&1 Internet AG page 6
  7. 7. Primitive Reference Date Types Types Boolean Error Number RegExp String Object null Array undefined Function Andreas Ecker | 1&1 Internet AG page 7
  8. 8. typeof Boolean quot;booleanquot; Number quot;numberquot; String quot;stringquot; null Caution! quot;objectquot; undefined quot;undefinedquot; Array Caution! quot;objectquot; Function quot;functionquot; Object quot;objectquot; Andreas Ecker | 1&1 Internet AG page 8
  9. 9. Object unordered collection of properties with arbitrary values object literal var obj = { name: quot;Joequot;, age: 26 }; setting a property obj.lastName = quot;Smithquot;; retrieving properties alert(obj.name + quot; quot; + obj.lastName); Andreas Ecker | 1&1 Internet AG page 9
  10. 10. Object as Hash Data structure that associates arbitrary values with arbitrary strings property name as an identifier obj.lastName = quot;Smithquot;; property name as a string obj[quot;lastNamequot;] = quot;Smithquot;; for( prop in obj ) { alert( prop + quot;: quot; + obj[prop] ); } Andreas Ecker | 1&1 Internet AG page 10
  11. 11. Class Concept of a class does not exist... ... but use a function as a constructor: class “Dog” function Dog() {}; instance “lassie” var lassie = new Dog; alert(lassie instanceof Dog); // true Andreas Ecker | 1&1 Internet AG page 11
  12. 12. Static Members Because functions are „first-class objects“ we can attach properties: Class Variables Dog.SPECIES = quot;Canis lupusquot;; Class Methods Dog.getCount = function() { return Dog.COUNT; }; Andreas Ecker | 1&1 Internet AG page 12
  13. 13. Instance Members Instance Variables function Dog(name) { this.name = name; }; var lassie = new Dog(quot;Lassiequot;); alert( lassie.name ); Andreas Ecker | 1&1 Internet AG page 13
  14. 14. Instance Members Instance Methods function Dog(name) { this.name = name; this.bark = function() { alert(quot;Woof!quot;) }; }; var lassie = new Dog(quot;Lassiequot;); lassie.bark(); Andreas Ecker | 1&1 Internet AG page 14
  15. 15. Scope Global Scope Variables outside of any functions ● Variables inside functions without var ● var global1 = 1; global2 = 2; function foo() { global3 = 3; }; Andreas Ecker | 1&1 Internet AG page 15
  16. 16. Scope Function Scope Variables inside functions declared with var ● Function arguments ● function foo(local1) { var local2 = 2; }; Andreas Ecker | 1&1 Internet AG page 16
  17. 17. Scope Block Scope ... but can be faked: // before block (function() { // inside block })(); // after block Andreas Ecker | 1&1 Internet AG page 17
  18. 18. Private Members function Dog(name) { var _name = name; // private variable // privileged method this.getName = function() { return _name; }; }; var lassie = new Dog(quot;Lassiequot;); alert( lassie.getName() ); Andreas Ecker | 1&1 Internet AG page 18
  19. 19. Private Members function Dog(name) { var _name = name; // private method var _fixName = function() { return _name.toUpperCase(); }; this.getName = function(){ return _fixName(); }; }; Andreas Ecker | 1&1 Internet AG page 19
  20. 20. Closures Nested functions Inner function has still access to local variables even after the outer function has finished Andreas Ecker | 1&1 Internet AG page 20
  21. 21. Closures function outer() { var count = 1; function inner() { alert(count++) } return inner; } var myClosure = outer(); myClosure(); // ==> 1 myClosure(); // ==> 2 Andreas Ecker | 1&1 Internet AG page 21
  22. 22. Inheritance (native) Pet function Pet() {}; function Dog() {}; Dog Dog.prototype = new Pet; Andreas Ecker | 1&1 Internet AG page 22
  23. 23. Calling the superclass' constructor function Pet(name) { this.name = name; }; function Dog(name) { // super(name) Pet.call( this, name ); this.bark = function() {}; }; Dog.prototype = new Pet; Andreas Ecker | 1&1 Internet AG page 23
  24. 24. Calling a Method with Arbitrary Scope Inside the method this now refers to the scope you supplied: function foo() { this.bar(); }; foo.call( scope, arg1, arg2, ... ); foo.apply( scope, [arg1, arg2, ...] ); Andreas Ecker | 1&1 Internet AG page 24
  25. 25. Instance Members (improvement) // old: attach to quot;thisquot; function Dog(name) { this.bark = function(){ alert(quot;Woof!quot;) }; }; // new: attach to quot;prototypequot; function Dog(name) {}; Dog.prototype.bark = function(){ alert(quot;Woof!quot;) }; }; Andreas Ecker | 1&1 Internet AG page 25
  26. 26. Prototype Chain undefined no Pet found? yes no Dog found? yes no lassie: Dog found? yes lassie.name Andreas Ecker | 1&1 Internet AG page 26
  27. 27. Instance vs. Prototype Property values on instance: local, instance-specific values Property values on prototype: read-only default values Attaching to the prototype saves memory, especially for large numbers of instances Andreas Ecker | 1&1 Internet AG page 27
  28. 28. Class Augmentation Affects all new instances Affects all existing instances Allows modification of existing classes String.prototype.trim = function() { return this.replace(/^s+/, quot;quot;); }; alert(quot; Lassiequot;.trim() ); Andreas Ecker | 1&1 Internet AG page 28
  29. 29. Overriding Methods function Dog() {}; Dog.prototype.bark = function() { alert(quot;Woof!quot;) }; function Bulldog() {}; Bulldog.prototype = new Dog; Bulldog.prototype.bark = function() { // super.bark(); Dog.prototype.bark.call(this); alert(quot;Grrrh!!quot;) }; Andreas Ecker | 1&1 Internet AG page 29
  30. 30. Abstract Class function Pet() { if(this._id == Pet._id) { throw new Error(quot;No Pets, please!quot;); } } Pet._id = quot;Petquot;; Pet.prototype._id = quot;Petquot;; var fiffy = new Pet; // Error (intended) Andreas Ecker | 1&1 Internet AG page 30
  31. 31. Inheritance (improved) But now our code to setup inheritance will fail: Dog.prototype = new Pet; // Error :-( Solution: Do not create an instance of the actual superclass just to setup inheritance, use a dummy: function Dummy() {}; Dummy.prototype = Pet.prototype; Dog.prototype = new Dummy; Andreas Ecker | 1&1 Internet AG page 31
  32. 32. Namespaces if (typeof very == quot;undefinedquot;) { very = {}; } if (typeof very.cute == quot;undefinedquot;) { very.cute = {}; } very.cute.Dog = function() {}; var fiffy = new very.cute.Dog; Andreas Ecker | 1&1 Internet AG page 32
  33. 33. Singleton (“Essence”) // The Last of the Mohicans var chingachgook = { fight : function() { alert(quot;Woah!quot;); } }; chingachgook.fight(); Andreas Ecker | 1&1 Internet AG page 33
  34. 34. Singleton (“Ceremony”) function Mohican() { this.fight = function(){alert(quot;Woah!quot;)} }; Mohican.getInstance = function() { if (!this._instance) { this._instance = new this; } return this._instance; }; Mohican.getInstance().fight(); Andreas Ecker | 1&1 Internet AG page 34
  35. 35. Ceremony Essence Andreas Ecker | 1&1 Internet AG page 35
  36. 36. Ceremony Essence Andreas Ecker | 1&1 Internet AG page 36
  37. 37. OO Wishlist Closed form of class declaration Namespaces Static members Instance members Inheritance Superclass call (constructor, overriden methods) Andreas Ecker | 1&1 Internet AG page 37
  38. 38. http://qooxdoo.org Open-Source JavaScript Framework Andreas Ecker | 1&1 Internet AG page 38
  39. 39. Class Declaration qx.Class.define( quot;very.cute.Dogquot;, { extend: Dog, construct: function(name) { this.base( arguments, name); }, statics: { SPECIES: quot;Canis lupus familiarisquot; }, members: { bark: function() { alert(quot;wooofquot;);}} } ); Andreas Ecker | 1&1 Internet AG page 39
  40. 40. OO Wishlist (continued) Static class Abstract class Singleton Andreas Ecker | 1&1 Internet AG page 40
  41. 41. Static Class qx.Class.define( quot;DogUtilquot;, { type: quot;staticquot;, statics: { SPECIES: quot;Canis lupusquot;, getCount: function() {} } }); Andreas Ecker | 1&1 Internet AG page 41
  42. 42. Abstract Class qx.Class.define( quot;Petquot;, { type: quot;abstractquot;, construct: function(name) { this.name = name; }, members: { getName: function() { return this.name; } } }); Andreas Ecker | 1&1 Internet AG page 42
  43. 43. Singleton qx.Class.define( quot;Mohicanquot;, { type: quot;singletonquot;, members: { fight: function() { alert(quot;Woah!quot;); } } }); var chingachgook = Mohican.getInstance() chingachgook.fight(); Andreas Ecker | 1&1 Internet AG page 43
  44. 44. OO Wishlist (continued) Destructors Andreas Ecker | 1&1 Internet AG page 44
  45. 45. Destructor qx.Class.define( quot;very.cute.Dogquot;, { construct: function() { this._toys = new some.complex.Toy; }, destruct: { this._disposeObjects(quot;_toysquot;); } }); Andreas Ecker | 1&1 Internet AG page 45
  46. 46. OO Wishlist (continued) Getters Setters Andreas Ecker | 1&1 Internet AG page 46
  47. 47. Dynamic Properties qx.Class.define( quot;very.cute.Dogquot;, { properties: { name: { check: quot;Stringquot; } } }); var fiffy = very.cute.Dog; fiffy.setName(quot;Fiffyquot;); alert( fiffy.getName() ); Andreas Ecker | 1&1 Internet AG page 47
  48. 48. OO Wishlist (continued) Interfaces Definition of (empty) methods, that a class must implement individually Mixins Definition of (non-empty) methods, etc. that are added to an existing class Andreas Ecker | 1&1 Internet AG page 48
  49. 49. Interfaces qx.Interface.define( quot;IVenomousquot;, { members: { actionToKill: function() {} } }); qx.Class.define( quot;Snakequot;, implement: IVenomous, members: { actionToKill: function() { /* bite code here */ } }); Andreas Ecker | 1&1 Internet AG page 49
  50. 50. Mixins qx.Mixin.define( quot;MMigrantquot;, { members: { leave: function() { /* code! */ }, return: function() { /* code! */ }, } }); qx.Class.define( quot;Storkquot;, include: [MMigrant, MClattering] }); Andreas Ecker | 1&1 Internet AG page 50
  51. 51. Aspect-oriented Propramming (AOP) Attach advices before or after each function call qx.core.Aspect.addAdvice( quot;beforequot;, // or quot;afterquot; quot;*quot;, // or quot;memberquot;, quot;staticquot;, // quot;constructorquot;, // quot;destructorquot;, quot;propertyquot; quot;your.namespace.*quot;, // regexp myAdvice ); Andreas Ecker | 1&1 Internet AG page 51
  52. 52. Aspect-oriented Propramming (AOP) Signature of advice function: myAdvice( fullName, // full function name target, // function to call type, // quot;beforequot; or quot;afterquot; args, // arguments to target retValue // only for quot;afterquot; advice ); Andreas Ecker | 1&1 Internet AG page 52
  53. 53. ☺ Please try that at home http://qooxdoo.org qooxdoo: OO Documentation qooxdoo: API Viewer Crockford: JavaScript Survey Crockford: Private Members Flanagan: JavaScript (O'Reilly) andreas.ecker@1und1.de Andreas Ecker | 1&1 Internet AG page 53

×