I'm reading "JavaScript the Good Parts" and it mentions cascades as a way to do method chaining in JavaScript but I can't find any code that explains how these methods should be implemented.
getElement('myBoxDiv').
move(350, 150).
width(100).
height(100).
color('red').
border('10px outset').
padding('4px').
appendText("Please stand by").
on('mousedown', function (m) {
this.startDrag(m, this.getNinth(m));
}).
on('mousemove', 'drag').
on('mouseup', 'stopDrag').
later(2000, function ( ) {
this.
color('yellow').
setHTML("What hath God wraught?").
slide(400, 40, 200, 200);
}).
tip('This box is resizeable');
I'm reading "JavaScript the Good Parts" and it mentions cascades as a way to do method chaining in JavaScript but I can't find any code that explains how these methods should be implemented.
getElement('myBoxDiv').
move(350, 150).
width(100).
height(100).
color('red').
border('10px outset').
padding('4px').
appendText("Please stand by").
on('mousedown', function (m) {
this.startDrag(m, this.getNinth(m));
}).
on('mousemove', 'drag').
on('mouseup', 'stopDrag').
later(2000, function ( ) {
this.
color('yellow').
setHTML("What hath God wraught?").
slide(400, 40, 200, 200);
}).
tip('This box is resizeable');
Share
Improve this question
asked Apr 16, 2009 at 23:48
ChadChad
6 Answers
Reset to default 6The trick is that the method itself should only return this
. That way, each time you chain these methods together, the object itself is the base of the call.
SomeObj.width(40) would then return just SomeObj, so adding the call .height(50) would function, and continue along.
In a cascade, we can call many methods on the same object in sequence in a single statement. Lets try this example,
var Calc = function(){
this.result=0;
this.add = function(){
for(var x=0; x<arguments.length; x++){
this.result += arguments[x];
}
return this;
};
this.sub = function(){
for(var x=0; x<arguments.length; x++){
this.result -= arguments[x];
}
return this;
};
this.mult = function(){
if(this.result==0)this.result = 1;
for(var x=0; x<arguments.length; x++){
this.result *= arguments[x];
}
return this;
};
this.div = function(){
if(this.result==0) return this;
for(var x=0; x<arguments.length; x++){
this.result /= arguments[x];
}
return this;
};
this.eq = function(){
return this.result
};
}
var cal1 = new Calc();
cal1.add(3).sub(1).add(2) // Here result = 4;
These methods always return the object they belong to this
, e.g.:
var txtProcesor = {
txt: '',
removeWhite: function () {
this.txt = this.txt.replace(/\s+/g, '');
return this;
},
evenToUp: function () {
var res = "";
for (var i = 0; i < this.txt.length; i++) {
if (i % 2 == 0) res += this.txt[i].toUpperCase();
else res += this.txt[i];
}
this.txt = res;
return this;
}
}
txtProcesor.txt = " abc def ";
alert(txtProcesor.removeWhite().evenToUp().txt);
This is basically the way JQuery works. The idea is to make each of those functions return objects which contain those functions again so to speak.
EDIT: You can download JQuery and look at the source code for it, because this is exactly what is going on in that library.
Here is a demo combine cascade with callback, and the usage, hope this will help.
let calNum = function(num) {
this.num = num;
this.add = function(dif, callback) {
this.num = this.num + dif;
callback(this.num);
return this;
}
this.sub = function(dif, callback) {
this.num = this.num - dif;
callback(this.num);
return this;
}
this.multi = function(m, callback) {
this.num = this.num * m;
callback(this.num);
return this;
}
return this;
};
calNum(3).add(3,function(result) {
console.log(result);
}).multi(2, function(result) {
console.log(result);
}).sub(1, function(result) {
console.log(result);
}); // The final result is 11
I was also going through the same book but didn't find any implementation of the concept. However I found this nice and short blog on this.
Here is how you can enable cascades:
function number(value) {
this.value = value;
this.plus = function (sum) {
this.value += sum;
return this;
};
this.return = function () {
return this.value;
};
return this;
}
console.log(new number(5).plus(1).return());