JavaScript, as you may know, does not have very strict type checking. The typeof operator can pretty much only tell you the difference between Strings, Numbers, and Objects. This just isn’t going to cut it if you need to make decisions based on specific Object types, including custom Objects. The good news is there is a way to get at this information in JavaScript pretty easily:
var test_string = 'Hello',
test_array = ['one', 'two', 'three'],
test_number = 42;
test_object = { key: 'value' };
test_function = function() {};
test_string.constructor == String;// true
test_array.constructor == Array;// true
test_number.constructor == Number;// true
test_object.constructor == Object;// true
test_function.constructor == Function;// true
test_string.constructor == Object;// false
test_array.constructor == Object;// false
test_number.constructor == Object;// false
test_object.constructor == Function;// false
test_function.constructor == Object;// false
The only drawback is that it’s a bit cumbersome, and a little confusing. I like to wrap this in a bit of sugar.
function is_typeof(type, suspect) {
if (type === undefined) {
throw new Error('is_typeof(type, suspect): type is undefined.');
}
if (suspect === undefined) {
throw new Error('is_typeof(type, suspect): suspect is undefined.');
}
return suspect.constructor == type;
}
Note: I use snake case because I like it, feel free to judge me and change it to something you’d prefer.
I go with is_typeof because it’s a little more definitive and it bears resemblance to the well-known typeof keyword so it indicates what it does. I’m open to better names for this one but I think it’s short sweet and to the point.
This may look a bit weird, but it makes for a pretty clear syntax. Let’s take a look at this in action:
function Unicorn(arg) {
if (is_typeof(String, arg)) {
this.name = arg;
}
if (is_typeof(Object, arg)) {
var obj = arg;
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
this[prop] = obj[prop];
}
}
}
return Unicorn;
};
Here’s a simple example of a basic custom object, with the ability to accept either a string or an object in the constructor. This gives us a sort-of dual API to create Unicorns. How sweet is that. Seriously, you can make some pretty useful functions with this pattern. Although I should point out that you shouldn’t do this just because you can, this technique is an investment in complexity and too much of it is unhealthy. If you’re testing, which you should be, this adds a significant amount of surface area to test. It works great for constructors and cases where you want the same basic action to be run with more or less data.
This is only one simple technique using the is_typeof method. Another use is hardening up your code by making strict type requirements, among others. It’s a good trick to have in your bag and it’s syntax makes it pretty easy to figure out at a glance. It really helps you write better code.
If you want to take this to the next level you can curry this function to make shorthand methods for any type you like:
function is_string(suspect) {
return is_typeof(String, suspect);
}
This makes code like the following pretty short and sweet:
var greeting = 'Hello World!';
if (is_string(greeting)) {
alert(greeting);
}
Latest Ninjs commits
- 2012-02-15 17:10 by Dayton Nolan
Regenerate gemspec for version 0.16.7 - 2012-02-15 17:10 by Dayton Nolan
Remove application file debugging - 2012-02-15 17:10 by Dayton Nolan
Version bump to 0.16.7 - 2012-02-15 17:08 by Dayton Nolan
Regenerate gemspec for version 0.16.6 - 2012-02-15 17:08 by Dayton Nolan
Version bump to 0.16.6 - 2012-02-15 17:08 by Dayton Nolan
Add interpolate_constants: false - 2012-02-15 16:56 by Dayton Nolan
Regenerate gemspec for version 0.16.5 - 2012-02-15 16:55 by Dayton Nolan
Ignore Gemfile.lcok - 2012-02-15 16:55 by Dayton Nolan
Version bump to 0.16.5 - 2012-02-15 16:54 by Dayton Nolan
Add custom sprockets - 2012-02-15 16:52 by Dayton Nolan
remove sprockets - 2012-02-15 16:48 by Dayton Nolan
Merge remote-tracking branch 'origin/v0.16.3' - 2012-02-15 16:48 by Dayton Nolan
Remove custom Sprockets - 2012-02-15 16:36 by Dayton Nolan
Regenerate gemspec for version 0.16.4 - 2012-02-15 16:36 by Dayton Nolan
Version bump to 0.16.4 - 2012-02-15 16:36 by Dayton Nolan
Regenerate gemspec for version 0.16.3 - 2012-02-15 16:35 by Dayton Nolan
Add Sprockets - 2012-02-15 16:33 by Dayton Nolan
Regenerate gemspec for version 0.16.4 - 2012-02-15 16:30 by Dayton Nolan
Vendorized Sprockets and fix from https://github.com/matehat/sprockets - 2012-02-15 16:22 by Dayton Nolan
Add test for Sprockets bug - 2011-10-28 19:50 by Dayton Nolan
Regenerate gemspec for version 0.16.3 - 2011-10-28 19:50 by Dayton Nolan
Version bump to 0.16.3 - 2011-10-28 19:50 by Dayton Nolan
Fix project specs - 2011-10-27 15:33 by Dayton Nolan
Regenerate gemspec for version 0.16.2 - 2011-10-27 15:33 by Dayton Nolan
Version bump to 0.16.2 - 2011-10-27 15:32 by Dayton Nolan
Fix dom ready error - 2011-10-27 15:13 by Dayton Nolan
Merge branch 'master' of github.com:daytonn/ninjs - 2011-10-21 04:46 by Dayton Nolan
Regenerate gemspec for version 0.16.1 - 2011-10-21 04:46 by Dayton Nolan
Version bump to 0.16.1 - 2011-10-21 04:08 by Dayton Nolan
Use jasmine for tests - 2011-10-21 03:41 by Dayton Nolan
Add jasmine for testing - 2011-09-30 20:39 by Dayton Nolan
Remove rubikon dependency and CNAME - 2011-09-23 23:57 by Dayton Nolan
Reset ninjs-framework submodule - 2011-09-19 03:54 by Dayton Nolan
Update ninjs-framework - 2011-09-19 03:53 by Dayton Nolan
Update ninjs-framework
- 2012-02-15 17:10 by Dayton Nolan



