Example:
function action(value) {
// I want to operate on a string
String(value)...;
}
When we pass dynamic values into JavaScript's primary types (String
, Number
, Boolean
, Object
, etc.) we can (for want of a better word) cast the value to the specified type.
Is it possible to build this feature in custom types, and how would I go about this?
Example of what I would like to do:
function action(value) {
Point(value)...;
// Value at this point (excuse the pun) is a point
// // *** Would like to see that intellisense is aware of the type at this point, but please don't assume this is ONLY for intellisense***
}
Is it possible to call constructor functions in this way and have the constructor function "cast" the value to an instance of itself - or does this only work for JavaScript's primary types?
Answer
Your custom constructor can just examine the typeof
the arguments that it is passed and behave accordingly. This isn't technically a "cast", but rather writing code to examine the types of the arguments and then decide on the proper behavior which can include converting from one type to another.
See How to overload functions in javascript? for a much longer description of how to examine arguments sent to any function and then adjust the behavior of the function based on the type and position and presence of the arguments. This same functionality can be used to do something that is "cast" like (though we don't usually think of casting in Javascript, but rather just converting).
We could give you actual code examples if you can be more specific about what types you want to "cast" in your Point constructor.
There are some simple examples of "cast" like things:
function delay(fn, t) {
// if t is passed as a string represeantation of a number,
// convert it to an actual number
return setTimeout(fn, +t);
}
Or, a little more interesting example that can take a number of ms, a string with units at the end or an object with properties:
function delay(fn, t) {
var typeT = typeof t, ms, matches, num, multiplier,
suffixes = {ms: 1, sec: 1000, min: 1000 * 60, hr: 1000 * 60 * 60};
if (typeT === "string") {
matches = t.match(/^([\d.]+)(.+)$/);
if (matches) {
num = +matches[1];
multiplier = suffixes[matches[2]];
if (multiplier) {
ms = num * multiplier;
}
}
} else if (typeT === "number") {
// plain number is milliseconds
ms = t;
} else if (typeT === "object" && t.units && t.value) {
multiplier = suffixes[t.units];
if (multiplier) {
ms = t.value * multiplier;
}
}
if (ms === undefined) {
throw new Error("Invalid time argument for delay()");
}
return setTimeout(fn, ms);
}
delay(myFn, "2.5hr");
delay(myFn, "25sec");
delay(myFn, 150);
delay(myFn, {units: "sec", value: 25});
No comments:
Post a Comment