Just curious:
- 4 instanceof Number => false
- new Number(4) instanceof Number => true?
Why is this? Same with strings:
'some string' instanceof Stringreturns falsenew String('some string') instanceof String=> trueString('some string') instanceof Stringalso returns false('some string').toString instanceof Stringalso returns false
For object, array or function types the instanceof operator works as expected. I just don’t know how to understand this.
[new insights]
Object.prototype.is = function() { var test = arguments.length ? [].slice.call(arguments) : null ,self = this.constructor; return test ? !!(test.filter(function(a){return a === self}).length) : (this.constructor.name || (String(self).match ( /^function\s*([^\s(]+)/im ) || [0,'ANONYMOUS_CONSTRUCTOR']) [1] ); } // usage var Newclass = function(){}; // anonymous Constructor function var Some = function Some(){}; // named Constructor function (5).is(); //=> Number 'hello world'.is(); //=> String (new Newclass()).is(); //=> ANONYMOUS_CONSTRUCTOR (new Some()).is(); //=> Some /[a-z]/.is(); //=> RegExp '5'.is(Number); //=> false '5'.is(String); //=> true
value instanceof Constructoris the same asConstructor.prototype.isPrototypeOf(value)and both check the [[Prototype]]-chain ofvaluefor occurences of a specific object.Strings and numbers are primitive values, not objects and therefore don’t have a [[Prototype]], so it’ll only work if you wrap them in regular objects (called ‘boxing’ in Java).
Also, as you noticed,
String(value)andnew String(value)do different things: If you call the constructor functions of the built-in types without using thenewoperator, they try to convert (‘cast’) the argument to the specific type. If you use thenewoperator, they create a wrapper object.new String(value)is roughly equivalent toObject(String(value)), which behaves the same way asnew Object(String(value)).Some more on types in JavaScript: ECMA-262 defines the following primitive types: Undefined, Null, Boolean, Number, and String. Additionally, there is the type Object for things which have properties.
For example, functions are of type Object (they just have a special property called [[Call]]), and
nullis a primitive value of type Null. This means that the result of thetypeofoperator doesn’t really return the type of a value…Aditionally, JavaScript objects have another property called [[Class]]. You can get it via
Object.prototype.toString.call(value)(this will return'[objectClassname]'). Arrays and functions are of the type Object, but their classes are Array and Function.The test for an object’s class given above works when
instanceoffails (e.g. when objects are passed between window/frame boundaries and don’t share the same prototypes).Also, you might want to check out this improved version of
typeof:For primitives, it will return their type in lower case, for objects, it will return their class in title case.
Examples:
For primitives of type Number (eg
5), it will return'number', for wrapper objects of class Number (egnew Number(5)), it will return'Number';For functions, it will return
'Function'.If you don’t want to discern between primitive values and wrapper objects (for whatever, probably bad reason), use
typeOf(...).toLowerCase().Known bugs are some built-in functions in IE, which are considered
'Object'and a return value of'unknown'when used with some COM+ objects.