53
Andreas Ecker | 1&1 Internet AG Advanced Object-Oriented JavaScript

Advanced Object-Oriented JavaScript

  • View
    14.332

  • Download
    3

Embed Size (px)

DESCRIPTION

Presentation at the Dynamic World Conference DLW 08 Europe

Citation preview

Page 1: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG

Advanced Object-OrientedJavaScript

Page 2: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 2

These keywords belong too ...

abstractbooleanbytecharclassconstdoubleenumexport

extendsfinalfloatimplementsimportintinterfacelongnative

throwstransientvolatile

packageprivateprotectedpublicshortstaticsupersynchronized

Page 3: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 3

... JavaScript !

ECMAScript 3 / JavaScript 1.5Standard spezified in 1999Supported by all common browsersMany keywords reserved, but not used

ECMAScript 4 / JavaScript 2.0Many new language featuresNot expected any time soon

Page 4: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 4

Data Types

Primitive Types

Reference Types

Page 5: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 5

Primitive Types

Boolean true, falseNumber 1, 3.141, -1.602e-19String "Joe"null nullundefined undefined

Page 6: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 6

Reference Types

Date new Date(1211623944453);Error new Error("Oops!");RegExp /^web.*$/i;Array [ "apple", "banana" ]Function function(x) {return x*x}

Page 7: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 7

Object

Number

String

null

undefined

Boolean

PrimitiveTypes Date

Function

Array

RegExp

Error

ReferenceTypes

Page 8: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 8

typeof

Boolean "boolean"Number "number"String "string"null "object" Caution!

undefined "undefined"Array "object" Caution!Function "function"Object "object"

Page 9: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 9

Object

unordered collection of properties witharbitrary values

object literalvar obj = { name: "Joe", age: 26 };

setting a propertyobj.lastName = "Smith";

retrieving propertiesalert(obj.name + " " + obj.lastName);

Page 10: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 10

Object as Hash

Data structure that associates arbitrary values with arbitrary strings

property name as an identifierobj.lastName = "Smith";

property name as a stringobj["lastName"] = "Smith";

for( prop in obj ) {alert( prop + ": " + obj[prop] );

}

Page 11: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 11

Class

Concept of a class does not exist...

... but use a function as a constructor:

function Dog() {};

var lassie = new Dog;

alert(lassie instanceof Dog); // true

class “Dog” instance “lassie”

Page 12: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 12

Static Members

Because functions are „first-class objects“ we can attach properties:

Class VariablesDog.SPECIES = "Canis lupus";

Class MethodsDog.getCount = function() { return Dog.COUNT;};

Page 13: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 13

Instance Members

Instance Variables

function Dog(name) { this.name = name;};

var lassie = new Dog("Lassie");alert( lassie.name );

Page 14: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 14

Instance Members

Instance Methods

function Dog(name) { this.name = name; this.bark = function() { alert("Woof!") };};

var lassie = new Dog("Lassie");lassie.bark();

Page 15: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 15

Scope

Global Scope

● Variables outside of any functions

● Variables inside functions without var

var global1 = 1;global2 = 2;

function foo() { global3 = 3;};

Page 16: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 16

Scope

Function Scope

● Variables inside functions declared with var● Function arguments

function foo(local1) { var local2 = 2;};

Page 17: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 17

Scope

Block Scope... but can be faked:

// before block(function() { // inside block

})();// after block

Page 18: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 18

Private Members

function Dog(name) {var _name = name; // private variable// privileged method this.getName = function() {

return _name;};

};

var lassie = new Dog("Lassie");alert( lassie.getName() );

Page 19: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 19

Private Members

function Dog(name) {var _name = name;// private methodvar _fixName = function() {

return _name.toUpperCase();};this.getName = function(){ return _fixName();};

};

Page 20: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 20

Closures

Nested functions

Inner function has still access to local

variables even after the outer function

has finished

Page 21: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 21

Closures

function outer(){ var count = 1;function inner() { }

return inner;}

var myClosure = outer();myClosure();myClosure();

alert(count++)

// ==> 1// ==> 2

Page 22: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 22

Inheritance (native)

function Pet() {};

function Dog() {};

Dog.prototype = new Pet; Dog

Pet

Page 23: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 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;

Page 24: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 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, ...] );

Page 25: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 25

Instance Members (improvement)

// old: attach to "this"function Dog(name) {

this.bark = function(){ alert("Woof!") };

};

// new: attach to "prototype"function Dog(name) {};

Dog.prototype.bark = function(){ alert("Woof!") };

};

Page 26: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 26

Prototype Chain

Dog

Pet

lassie: Dog found? yes

no

found? yes

no

found? yes

no

undefined

lassie.name

Page 27: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 27

Instance vs. Prototype

Property values on instance:local, instance-specific values

Property values on prototype:read-only default values

Attaching to the prototype savesmemory, especially for large numbersof instances

Page 28: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 28

Class Augmentation

Affects all new instancesAffects all existing instancesAllows modification of existing classes

String.prototype.trim = function() { return this.replace(/^\s+/, ""); };

alert(" Lassie".trim() );

Page 29: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 29

Overriding Methods

function Dog() {};Dog.prototype.bark =

function() { alert("Woof!") };

function Bulldog() {};Bulldog.prototype = new Dog;

Bulldog.prototype.bark = function() { // super.bark();

Dog.prototype.bark.call(this);alert("Grrrh!!") };

Page 30: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 30

Abstract Class

function Pet() { if(this._id == Pet._id) { throw new Error("No Pets, please!"); }}Pet._id = "Pet";Pet.prototype._id = "Pet";

var fiffy = new Pet; // Error (intended)

Page 31: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 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;

Page 32: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 32

Namespaces

if (typeof very == "undefined") {very = {};

}if (typeof very.cute == "undefined") {

very.cute = {};}

very.cute.Dog = function() {};var fiffy = new very.cute.Dog;

Page 33: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 33

Singleton (“Essence”)

// The Last of the Mohicansvar chingachgook = { fight : function() { alert("Woah!"); }};

chingachgook.fight();

Page 34: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 34

Singleton (“Ceremony”)

function Mohican() { this.fight = function(){alert("Woah!")}};Mohican.getInstance = function() {

if (!this._instance) {this._instance = new this; }

return this._instance;};

Mohican.getInstance().fight();

Page 35: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 35

Ceremony Essence

Page 36: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 36

EssenceCeremony

Page 37: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 37

OO Wishlist

Closed form of class declaration

Namespaces

Static members

Instance members

Inheritance

Superclass call (constructor, overriden methods)

Page 38: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 38

http://qooxdoo.orgOpen-Source JavaScript Framework

Page 39: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 39

Class Declaration

qx.Class.define( "very.cute.Dog"

);

Dog, function(name) {

this.base( arguments, name); }, {

SPECIES: "Canis lupus familiaris" }, {

bark: function() { alert("wooof");}}

, {extend: construct:

statics:

members:

}

Page 40: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 40

OO Wishlist (continued)

Static class

Abstract class

Singleton

Page 41: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 41

Static Class

qx.Class.define( "DogUtil", {type: "static",statics: {

SPECIES: "Canis lupus",getCount: function() {}

}});

Page 42: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 42

Abstract Class

qx.Class.define( "Pet", {type: "abstract",construct: function(name) {

this.name = name;},members: {

getName: function() {return this.name; }

}});

Page 43: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 43

Singleton

qx.Class.define( "Mohican", {type: "singleton",members: { fight: function() { alert("Woah!"); }}

});

var chingachgook = Mohican.getInstance()chingachgook.fight();

Page 44: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 44

OO Wishlist (continued)

Destructors

Page 45: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 45

Destructor

qx.Class.define( "very.cute.Dog", {construct: function() {

this._toys = new some.complex.Toy;},destruct: {

this._disposeObjects("_toys");}

});

Page 46: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 46

OO Wishlist (continued)

Getters

Setters

Page 47: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 47

Dynamic Properties

qx.Class.define( "very.cute.Dog", {properties: { name: { check: "String" }}

});

var fiffy = very.cute.Dog;fiffy.setName("Fiffy");alert( fiffy.getName() );

Page 48: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 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

Page 49: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 49

Interfaces

qx.Interface.define( "IVenomous", {members: {

actionToKill: function() {} }});qx.Class.define( "Snake",

implement: IVenomous,members: { actionToKill: function() { /* bite code here */ }

});

Page 50: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 50

Mixins

qx.Mixin.define( "MMigrant", {members: {

leave: function() { /* code! */ },return: function() { /* code! */ },

}});

qx.Class.define( "Stork", include: [MMigrant, MClattering]

});

Page 51: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 51

Aspect-oriented Propramming (AOP)

Attach advices before or after each function call

qx.core.Aspect.addAdvice( "before", // or "after" "*", // or "member", "static", // "constructor", // "destructor", "property"

"your.namespace.*", // regexpmyAdvice

);

Page 52: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 52

Aspect-oriented Propramming (AOP)

Signature of advice function:

myAdvice( fullName, // full function name target, // function to call type, // "before" or "after" args, // arguments to target retValue // only for "after" advice);

Page 53: Advanced Object-Oriented JavaScript

Andreas Ecker | 1&1 Internet AG page 53

Please try that at home

http://qooxdoo.orgqooxdoo: OO Documentationqooxdoo: API ViewerCrockford: JavaScript SurveyCrockford: Private MembersFlanagan: JavaScript (O'Reilly)[email protected]