Version 1.x
This file is written using a literate JavaScript. You can download
this cheatsheet to use as a local reference
or to run it locally.
If you prefer to see text as inline comments, just click on a sidebar
handle at the far right.
While dcl
works great in browsers using an AMD loader or
even simple <script>
, this tutorial is assumed to be run with
node.js.
For our examples we will need the main
dcl module:
file.js
1
| var dcl = require("dcl");
|
Declaring “classes”.
Declaring properties, constructors and methods
with dcl():
file.js
1
2
3
4
5
6
7
8
9
| var D = dcl(null, {
declaredClass: "D",
constructor: function(a, b, c){
console.log("something");
},
method: function(x, y){
return x + y;
}
});
|
No base class:
Single inheritance:
Mixins:
file.js
1
2
| var M = dcl(null, {});
var C = dcl([B, M], {});
|
Disposable one-off “class”:
file.js
1
| var x = new (dcl([B, M], {}))(1, 2, 3);
|
Supercalls
Make a super call passing through arguments
with dcl/superCall():
file.js
1
2
3
4
5
6
7
8
9
10
| var E = dcl(D, {
method: dcl.superCall(function(sup){
return function(x, y){
if(sup){
return sup.apply(this, arguments);
}
return 0;
};
})
});
|
Make a super call with different arguments:
file.js
1
2
3
4
5
6
7
8
9
10
| var F = dcl(D, {
method: dcl.superCall(function(sup){
return function(x, y){
if(sup){
return sup.call(this, x + 1, y - 1);
}
return 0;
};
})
});
|
Class-level AOP
Advise “before” with dcl.before():
file.js
1
2
3
4
5
| var H = dcl(D, {
method: dcl.before(function(){
console.log("Called with arguments: ", arguments);
})
});
|
Advise “after” with dcl.after():
file.js
1
2
3
4
5
| var I = dcl(D, {
method: dcl.after(function(args, result){
console.log("Returned result: ", result);
})
});
|
Advise “around” with dcl.around():
file.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| var J = dcl(D, {
method: dcl.around(function(sup){
return function(x, y){
console.log("Got: ", x, " and ", y);
if(sup){
try{
var result = sup.call(this, x, y);
console.log("Answered: ", result);
return result;
}catch(e){
console.log("Exception: ", e);
throw e;
}
}
};
})
});
|
Full-blown advising with dcl.advise():
file.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| var G = dcl(D, {
method: dcl.advise({
before: function(){
console.log("Called with arguments: ", arguments);
},
after: function(args, result){
console.log("Returned result: ", result);
},
around: function(sup){
return function(x, y){
console.log("Got: ", x, " and ", y);
if(sup){
try{
var result = sup.call(this, x, y);
console.log("Answered: ", result);
return result;
}catch(e){
console.log("Exception: ", e);
throw e;
}
}
};
}
})
});
|
Chaining
Chain after with dcl.chainAfter():
file.js
1
| dcl.chainAfter(D, "method1");
|
Chain before dcl.chainBefore():
file.js
1
| dcl.chainBefore(D, "method2");
|
Usually constructors are chained after, while destructors are chained before.
dcl
chains constructors automatically by default.
Object-level AOP
We need advise module:
file.js
1
2
3
| var advise = require("dcl/advise");
var x = new J;
|
Advise “before” with advise.before():
file.js
1
2
3
| var a1 = advise.before(x, "method", function(){
console.log("Called with arguments: ", arguments);
});
|
Advise “after” with advise.after():
file.js
1
2
3
| var a2 = advise.before(x, "method", function(args, result){
console.log("Returned result: ", result);
});
|
Advise “around” with advise.around():
file.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| var a3 = advise.around(x, "method", function(sup){
return function(x, y){
console.log("Got: ", x, " and ", y);
if(sup){
try{
var result = sup.call(this, x, y);
console.log("Answered: ", result);
return result;
}catch(e){
console.log("Exception: ", e);
throw e;
}
}
};
});
|
Full-blown advising with advise():
file.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| var a4 = advise(x, "method", {
before: function(){
console.log("Called with arguments: ", arguments);
},
after: function(args, result){
console.log("Returned result: ", result);
},
around: function(sup){
return function(x, y){
console.log("Got: ", x, " and ", y);
if(sup){
try{
var result = sup.call(this, x, y);
console.log("Answered: ", result);
return result;
}catch(e){
console.log("Exception: ", e);
throw e;
}
}
};
}
});
|
Unadvise (in any order):
Inherited
We need inherited
module (its value is actually not used):
file.js
1
| var inherited = require("dcl/inherited");
|
Make a super call passing through arguments
with inherited():
file.js
1
2
3
4
5
| var K = dcl(D, {
method: function(x, y){
return this.inherited(arguments);
}
});
|
Make a super call with different arguments:
file.js
1
2
3
4
5
| var L = dcl(D, {
method: function(x, y){
return this.inherited(arguments, [x + 1, y - 1]);
}
});
|
Make a super call (works in both strict and non-strict modes):
file.js
1
2
3
4
5
| var M = dcl(D, {
method: function(x, y){
return this.inherited(M, "method", arguments);
}
});
|
Make a super call with getInherited()
(works in both strict and non-strict modes):
file.js
1
2
3
4
5
6
7
8
9
| var N = dcl(D, {
method: function(x, y){
var sup = this.getInherited(N, "method");
if(sup){
return sup.call(this, x + 1, y - 1);
}
return 0;
}
});
|
Debugging
We need debug module (its inclusion adds
enhanced error reporting automatically):
file.js
1
2
3
4
5
6
| var dclDebug = require("dcl/debug");
var O = dcl(null, {
declaredClass: "O"
});
var x = new O();
|
Log a class with dclDebug.log():
Log an object: