Reputation: 11773
Maybe I'm missing something obvious ... I've just started working with JavaScript, and when looking through an article about unit testing JavaScript with Jasmine, I came across this code:
function Convert(number, fromUnit) {
var conversions = {
distance : {
meters : 1,
cm : 0.01,
feet : 0.3048,
inches : 0.0254,
yards : 0.9144
},
volume : {
litres : 1,
gallons: 3.785411784,
cups : 0.236588236
}
},
betweenUnit = false,
type, unit;
for (type in conversions) {
if (conversions[type]) {
if ( (unit = conversions[type][fromUnit]) ) {
betweenUnit = number * unit * 1000;
}
}
}
return {
to : function (toUnit) {
if (betweenUnit) {
for (type in conversions) {
if (conversions.hasOwnProperty(type)) {
if ( (unit = conversions[type][toUnit]) ) {
return fix(betweenUnit / (unit * 1000));
}
}
}
throw new Error("unrecognized to-unit");
} else {
throw new Error("unrecognized from-unit");
}
function fix (num) {
return parseFloat( num.toFixed(2) );
}
}
};
}
It puzzled me as to why/how it is used, and what's the reason for it. It appears to return an object, which is a labeled function (method really, according to JavaScript naming convention), which wouldn't be called or returned upon creation.
After pondering about this and running it in chrome dev tools, it hit me that being called Convert
with a capital C
, it might be used as a constructor that would be used with new
(again, according to JavaScript naming convention) so I might create an object like:
var tenFeet = new Convert(10, 'feet');
and then use it as tenFeet.to('cm');
.
This still makes no sense, since I wouldn't call the object (read: class) Convert
, since it's not converting. I'd call the to
method convertTo
, and probably name Convert
to Measurement
or something.
Convert
with the same method?Cheers, and thanks in advance.
Upvotes: 0
Views: 617
Reputation: 11773
Blender answered this correctly, but just in case other people stumble upon page, here's a little more info on what's happening.
Coming from more "formal" languages, I guess I was having issues with the "label" appearance of the to
in the return statement.
from MDN on Label:
Summary
Provides a statement with an identifier that you can refer to using a break or continue statement.For example, you can use a label to identify a loop, and then use the break or continue statements to indicate whether a program should interrupt the loop or continue its execution.
Syntax
label : statement
Do notice that if you're creating an object, the syntax is similar. For example:
person={firstname:"John",lastname:"Doe",age:50,eyecolor:"blue"};
This will result in an object looking like:
object {firstname: "John", lastname: "Doe", age: 50, eyecolor: "blue"}
Another note is that if you're creating an array, you'll just use the commas, like this:
person=["John","Doe",50,"blue"];
This will give an array looking like:
["John", "Doe", 50, "blue"]
It takes a bit of time to get used to JavaScript syntax and logic, but all that really happens in my example is that the function returns an object, that has a method (named to
) defined on it.
Once you have that object, you can call the method on it using the usual dot notation, which results in the chaining
that is used in the above case. Or reusing Blender's example:
Convert(10, 'meters').to('feet') === 32.81`
Upvotes: 0
Reputation: 298452
This is following the "read like a sentence" paradigm that some people like:
Convert(10, 'meters').to('feet') === 32.81
// Convert 10 meters to feet
You're right, the function goes against common naming conventions, but you can sort of guess that it shouldn't be created with the new
keyword because there are no references to this
in the function body.
This problem could've been avoided with proper documentation.
Upvotes: 1