In his "Good Parts," Crockford suggests that 'new' should never be used. To follow that rule, how would you refactor the following code?
function Range(from, to) {
this.from = from;
this.to = to;
}
Range.prototype = {
includes: function(x) {
return this.from <= x && x <= this.to;
},
foreach: function(f) {
for(var x = Math.ceil(this.from); x <= this.to; x++) f(x);
},
toString: function() {
return "(" + this.from + "..." + this.to + ")";
}
};
// Here are example uses of a range object
var r = new Range(1,3); // Create a range object
r.includes(2); // => true: 2 is in the range
r.foreach(console.log); // Prints 1 2 3
I spotted his additional advice, but it wasn't clear how to apply it in this (presumably very common) case. Would he propose to create a factory function that contains a giant object literal? If yes, isn't that inefficient? ISTM that such a factory function, upon each invocation, creates duplicate functions. In other words, there is no one prototype holding shared custom methods.
It seems something is left unsaid in his advice, I'm hoping someone can clear it up.
Here I am showing how you can achieve this without using new
Range = function(from, to) {
function includes(x) {
return this.from <= x && x <= this.to;
}
function foreach(f) {
for (var x = Math.ceil(this.from); x <= this.to; x++) f(x);
}
function toString(){
return "(" + this.from + "..." + this.to + ")";
}
return {
from: from,
to: to,
includes: includes,
foreach: foreach,
toString: toString
};
};
var r = Range(1, 3);
console.log(r.includes(2)); // => true: 2 is in the range
r.foreach(console.log); // Prints 1 2 3
This is just an example, but I would follow what @nnnnnn is saying - "use it only when appropriate. As far as I'm concerned the code in your question is perfectly fine use of new and doesn't need to be refactored."
EDIT:
The code given below will avoid creating duplicate instances of functions
Range = function(from, to) {
return {
from: from,
to: to,
includes: Range.includes,
foreach: Range.foreach,
toString: Range.toString
};
};
Range.includes = function(x) {
return this.from <= x && x <= this.to;
}
Range.foreach = function (f) {
for (var x = Math.ceil(this.from); x <= this.to; x++) f(x);
}
Range.toString = function() {
return "(" + this.from + "..." + this.to + ")";
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With