2012年3月18日星期日

Enhanced typeof() operator in JavaScript

Javascript is weakly typed, and its type system always behaves different than your expectation.

Javascript provide typeof operator to test the type of a variable. it works fine generally. e.g.
typeof(1) === 'number'
typeof('hello') === 'string'
typeof({}) === 'object'
typeof(function(){}) === 'function'

But it is not enough, it behaves stupid when you dealling with objects created by constructors. e.g.
if you expected typeof(new Date('2012-12-12')) === 'date', then you must be disappointed, since actually typeof(new Date('2012-12-12')) === 'object'.
Yes, when you apply typeof() opeartor on any objects, it just yield the general type "object" rather than the more meaningful type "date".

How can we make the typeof() operator works in the way as we expected?
As we know when we create a object, the special property of the object constructor will be set to the function that create the object. which means:
(new Date('2012-1-1')).constructor === [Function Date]
So ideally we can retrieve the name of the function as the type of the variable. And to be compatible with javascript's native operator, we need to convert the name to lower case. So we got this expression
(new Date('2012-1-1')).constructor.name.toLowerCase() === 'date'
And luckily, we can also apply this to other primitive types, e.g:
(123).constructor.name.toLowerCase() === 'number'
('hello').constructor.name.toLowerCase() === 'string'
(function(){}).constructor.name.toLowerCase() === 'function'
or even
({}).constructor.name.toLowerCase() === 'object'
So in general, we use this expression as new implementation of the typeof() operator! EXCEPT One case!

If someone declare the object constructor in this way, our new typeof() implementation will work inproperly!

var SomeClass = (function() {
return function() {
this.someProperty='some value';
}
})();

or even define the constructor like this

var SomeClass = function() {
this.someProperty = 'some value';
}

And we will find that 
(new SomeClass).constructor.name.toLowerCase() === ''
the reason behind this is because the real constructor of the SomeClass is actually an anonymous function, whose name is not set.

To solve this problem, we need to declare the name of the constructor:
var SomeClass = (function() {
return function SomeClass() {
this.someProperty='some value';
}
})();

or even define the constructor like this

var SomeClass = function SomeClass() {
this.someProperty = 'some value';
}

Best regards,

TimNew
-----------
If not now then when?
If not me then who?

Release your passion
To realize your potential

Sent with Sparrow

Posted via email from 米良的实验室

没有评论:

发表评论