joose - javascript meta object system
DESCRIPTION
Introduction to JavaScript development with JooseTRANSCRIPT
Software-Development with JavaScript and JooseHamburg, 22.Oktober 2008
No Agenda
Agenda
Joose isa meta object system for JavaScript
Joose is not
a browser/DOM/Ajax/Widget library like jQuery, Prototype, YUI,
Mootools or Dojo
Joose is not
a browser/DOM/Ajax/Widget library like jQuery, Prototype, YUI,
Mootools or Dojo You wil still very much need these when
you use Joose in the Browser
Joose helps
_ write
_ well structured,
_ expressive,
_ declarative,
_ maintainable
_ JavaScript applications.
Core Features
_ Classes
_ Interfaces
_ Mixins
_ Modules / Packages / Namespaces
_ Roles
_ (Mixins + Interfaces)
_ Method Modifiers
_ (think aspect oriented programming)
Core Features
Declarative methods to build all these things
Meta Features
Object based interface to introspect and manipulate all these things at
runtime.
Meta classes for classes, methods and attributes.
Meta?
Meta?
You don't need to understand the meta
features to work with Joose.
Meta?
You don't need to understand the meta
features to work with Joose.
But it is more fun if you do :)
Mission
Steal all the nice features from other programming languages.
Make them available in JavaScript in a way that feels native to JavaScript.
Java, C#, etc.
_ Classes
_ Interfaces
_ Packages / Namespaces
Smalltalk, CLOS (Common Lisp Object System)
_ Meta classes
_ Meta attributes
_ Meta methods
Ruby
_ Mixins
_ Meta classes
Perl 6
_ Roles
_ Method modifiers
_ Type constraints and coercions
Perl 5
_ Moose (All of the above)
LET‘S LOOK AT SOME CODE
a Class
Class("Point", {
})
with two attributes
Class("Point", { has: { x: {is: "ro"}, y: {is: "rw"}, }})
and a clear method
Class("Point", { has: { x: {is: "ro"}, y: {is: "rw"}, }, methods: { clear: function () { this.x = 0; this.setY(0); } }})
Inheritance
Class("Point3D", { isa: Point})
after...
Class("Point3D", { isa: Point, has: { z: {} }, after: { clear: function () { this.z = 0; } }})
before...
Class("Point3D", { isa: Point, has: { z: {} }, before: { clear: function () { this.z = 0; } }})
before...
Class("Point3D", { isa: Point, has: { z: {} }, override: { clear: function () { this.SUPER(); this.z = 0; } }})
Usage
var point = new Point3D();
point.setX(10);
var y = point.getY(10);
point.z = 1;
point.clear();
var point2 = new Point3D({ x: 10, y: 20 });
Modules
_ create a namespace
_ create a lexical scope for your code.
_ No need for ugly
_ (function () { ... })()
Bank.Account
Module("Bank", function (m) { Class("Account", { has: { balance: { is: "rw", init: 0 } } }})
JSON Integration
Class("Geometry.Point", { does: Joose.Storage, has: { x: {is: rw}, y: {is: rw}, $: { is: rw, init: "stuff", persistent: false } }})
JSON Integration
var p = new Geometry.Point({x: 10, y: 20}) var jsonSring = JSON.stringify(p); var p2 = JSON.parse(jsonString); alert(p2.getX())
JSON Integration
var p = new Geometry.Point({x: 10, y: 20}) var jsonSring = JSON.stringify(p); var p2 = JSON.parse(jsonString); alert(p2.getX())
Turn Joose Objects into JSON and turn JSON
into Joose objects
JSON Integration
var p = new Geometry.Point({x: 10, y: 20}) var jsonSring = JSON.stringify(p); var p2 = JSON.parse(jsonString); alert(p2.getX())
Turn Joose Objects into JSON and turn JSON
into Joose objects
Backend Integration!
Total JavaScript Makeover!
Classes and Namespaces in native JSif(Test == null) { Test = {};}
Test.StandardPoint = function (x, y) { this.x = x || 0 this.y = y || 0}
Test.StandardPoint.prototype = { getX: function () { return this.x }, setX: function (x) { this.x = x }, getY: function () { return this.y }, setY: function (y) { this.y = y; }, clear: function () { this.setX(0) this.setY(0) }}
Dramatization
Classes and Namespaces in native JS
if(Test == null) { Test = {};}
Test.StandardPoint = function (x, y) { this.x = x || 0 this.y = y || 0}
Test.StandardPoint.prototype = { getX: function () { return this.x }, setX: function (x) { this.x = x }, getY: function () { return this.y }, setY: function (y) { this.y = y; }, clear: function () { this.setX(0) this.setY(0) }}
Dramatization
Using Joose
Module("Test", function (m) { Class("Point", { has: { x: { is: "rw", init: 0 }, y: { is: "rw", init: 0 } }, methods: { clear: function () { this.setX(0); this.setY(0); } } })})
Using Joose
Module("Test", function (m) { Class("Point", { has: { x: { is: "rw", init: 0 }, y: { is: "rw", init: 0 } }, methods: { clear: function () { this.setX(0); this.setY(0); } } })})
No need for scrolling!
Class inheritance and method wrappers in native JS// We need a utility function to do the inheritancefunction inherit(superClass, subClass) { for(var i in superClass.prototype) { subClass.prototype[i] = superClass.prototype[i] }}
Test.StandardPoint3D = function (x, y, z) { this.x = x || 0 this.y = y || 0 this.z = z || 0}
// Make Test.Standard the super class of Test.StandardPoint3Dinherit(Test.StandardPoint, Test.StandardPoint3D)
// we cant assign a new prototype because we already have the one from the superTest.StandardPoint3D.prototype.getZ = function () { return this.z}
Test.StandardPoint3D.prototype.setZ = function (z) { this.z = z;}
var superMethod = Test.StandardPoint3D.prototype.clear;Test.StandardPoint3D.prototype.clear = function () { superMethod.apply(this); this.z = 0;}
Dramatization
Class inheritance and method wrappers in native JS
// We need a utility function to do the inheritancefunction inherit(superClass, subClass) { for(var i in superClass.prototype) { subClass.prototype[i] = superClass.prototype[i] }}
Test.StandardPoint3D = function (x, y, z) { this.x = x || 0 this.y = y || 0 this.z = z || 0}
// Make Test.Standard the super class of Test.StandardPoint3Dinherit(Test.StandardPoint, Test.StandardPoint3D)
// we cant assign a new prototype because we already have the one from the superTest.StandardPoint3D.prototype.getZ = function () { return this.z}
Test.StandardPoint3D.prototype.setZ = function (z) { this.z = z;}
var superMethod = Test.StandardPoint3D.prototype.clear;Test.StandardPoint3D.prototype.clear = function () { superMethod.apply(this); this.z = 0;}
Dramatization
Using Joose
Module("Test", function (m) { Class("Point3D", { isa: m.Point, has: { z: { is: "rw", init: 0 } }, after: { clear: function () { this.setZ(0) } } })})
EXAMPLES
Class Browser
_ http://it.test.avantaxx.de/xssinterface/projects/Joose/examples/class_browser.html
blok
_ http://blok.appspot.com
_ http://code.google.com/p/joose-js/source/browse/trunk/examples/blok/block/ui/Element.js
_ http://code.google.com/p/joose-js/source/browse/trunk/examples/blok/block/ui/role/Focusable.js
_ http://code.google.com/p/joose-js/source/browse/trunk/examples/blok/block/ui/role/Resizable.js
File Size
_ Minified: 56 kb
_ GZipped: 16 kb
Speed
Should be fine if you're not building a canvas based ray tracer for real time
animations.
Profiling shows that Joose's overhead is negligible in most real world
applications.
Speed
Should be fine if you're not building a canvas based ray tracer for real time
animations.
Profiling shows that Joose's overhead is negligible in most real world
applications.
Tell me if you do, though!
Other Frameworks
_ Integration with jQuery works like a charm
_ YUI should be fine, too (Because YUI is very serious about namespaces).
_ Others should be fine as well
Joose does not
_ extend any default object prototypes.
Object.prototype.boom = function () {
alert(„Dont try this at home“)
}
Joose runs
_ in all common browsers
_ Rhino
_ JScript.NET
_ Flash comming soon
_ Ensured by an extensive automated test suite.
Joose runs
_ in all common browsers
_ Rhino
_ JScript.NET
_ Flash comming soon
_ Ensured by an extensive automated test suite.
No extra testing in IE6 required :)
Use cases?
Joose is not always the right tool for the job!
Use it if
You need more than three "classes".
It makes sense to maintain page state in objects.
Advanced Topics
_ Backend Integration
_ Prototype based object orientation
_ Everything Meta
_ DOM Binding
_ Client Side Databases
More Info
_ http://code.google.com/p/joose-js/
_ http://joose-js.blogspot.com
Thank You