What is the difference between `this instanceof String` and `"foo" instanceof String`? - javascript

I'm extending Object like this:
Object.prototype.is_a = function (x) {
return this instanceof x;
}
All works as expected
"foo".is_a(String) // true
"foo".is_a(Object) // true
"foo".is_a(Array) // false
"foo".is_a(Function) // false
"foo".is_a(Boolean) // false
"foo".is_a(Date) // false
"foo".is_a(Number) // false
"foo".is_a(RegExp) // false
but, when
"foo" instanceof String // false
this keyword on the is_a() function is same as foo right? Why does it return different results?

First of all, you cannot apply instanceof to primitive values, that's why
"foo" instanceof String
returns false. Primitives are not objects and hence cannot be an instance of a constructor function. *
So why does it seem to work inside the is_a method?
In non-strict mode, the value of this inside a function is always going to be an object (step 3). If this value is not an object, it is implicitly converted to one. You can test this with console.log(typeof this).
That means that the string primitive "foo" is converted to an String object new String("foo") and that's why you can use instanceof on it.
In strict mode, the value of this doesn't have to be an object and is not automatically converted (step 1). Your method would fail in that case:
> Object.prototype.is_a = function (x) {
'use strict';
return this instanceof x;
}
> "foo".is_a(String)
false
*: That's a very simplified explanation. In reality, the instanceof operator delegates the evaluation to the constructor function's internal [[HasInstance]] method, which is defined to return false if the passed value is not an object.

String literals aren't the same as String objects (MDN). It appears that the string literal (which is a string primitive) is automatically boxed into an object when it's used as the binding context of a function (i.e. when it's this inside a function):
>>> typeof "foo"
"string"
>>> Object.prototype.type_of = function (x) {
return typeof this;
}
function (x) {
return typeof this;
}
>>> "foo".type_of()
"object"
That explains your instanceof behavior, as well. This behaves as you might expect:
>>> new String("foo") instanceof String
true
>>> new String("foo") instanceof Object
true
>>> new String("foo").is_a(String)
true
>>> new String("foo").is_a(Object)
true
>>> new String("foo").is_a(Array)
false

JavaScript has both primitive and object versions of strings, numbers and booleans. String literals define primitives rather than objects. If you did typeof "foo", you would get "string" rather than "object". But when you access a property of the string, it creates a temporary String object from the primitive string and then accesses the corresponding property of that object, so it this instanceof String is true inside that temporary String object's method.
In order to test whether something is a string while accounting for both primitives and objects, you need to test typeof foo === "string" || foo instanceof String.

instanceof needs an object defined, this example returns true:
var f = new String("foo");
alert( f instanceof String);
This is more similar to your example:
alert( new String("foo") instanceof String);

Related

Why `0 instanceof Number` is false? [duplicate]

"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
// the tests against Object really don't make sense
Array literals and Object literals match...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Why don't all of them? Or, why don't they all not?
And, what are they an instance of, then?
It's the same in FF3, IE7, Opera, and Chrome. So, at least it's consistent.
Primitives are a different kind of type than objects created from within Javascript. From the Mozilla API docs:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
I can't find any way to construct primitive types with code, perhaps it's not possible. This is probably why people use typeof "foo" === "string" instead of instanceof.
An easy way to remember things like this is asking yourself "I wonder what would be sane and easy to learn"? Whatever the answer is, Javascript does the other thing.
I use:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Because in JavaScript strings can be literals or objects.
In JavaScript everything is an object (or may at least be treated as an object), except primitives (booleans, null, numbers, strings and the value undefined (and symbol in ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
As you can see objects, arrays and the value null are all considered objects (null is a reference to an object which doesn't exist). Functions are distinguished because they are a special type of callable objects. However they are still objects.
On the other hand the literals true, 0, "" and undefined are not objects. They are primitive values in JavaScript. However booleans, numbers and strings also have constructors Boolean, Number and String respectively which wrap their respective primitives to provide added functionality:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
As you can see when primitive values are wrapped within the Boolean, Number and String constructors respectively they become objects. The instanceof operator only works for objects (which is why it returns false for primitive values):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
As you can see both typeof and instanceof are insufficient to test whether a value is a boolean, a number or a string - typeof only works for primitive booleans, numbers and strings; and instanceof doesn't work for primitive booleans, numbers and strings.
Fortunately there's a simple solution to this problem. The default implementation of toString (i.e. as it's natively defined on Object.prototype.toString) returns the internal [[Class]] property of both primitive values and objects:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
The internal [[Class]] property of a value is much more useful than the typeof the value. We can use Object.prototype.toString to create our own (more useful) version of the typeof operator as follows:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
Hope this article helped. To know more about the differences between primitives and wrapped objects read the following blog post: The Secret Life of JavaScript Primitives
You can use constructor property:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
you can use this, it will work for both case as
var text="foo"; // typeof will work
String text= new String("foo"); // instanceof will work
This is defined in the ECMAScript specification Section 7.3.19 Step 3: If Type(O) is not Object, return false.
In other word, if the Obj in Obj instanceof Callable is not an object, the instanceof will short-circuit to false directly.
I believe I have come up with a viable solution:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
The primitive wrapper types are reference types that are automatically created behind the scenes whenever strings, num­bers, or Booleans
are read.For example :
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
This is what happens behind the scenes:
// what the JavaScript engine does
var name = "foo";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);
Because the second line uses a string (a primitive) like an object,
the JavaScript engine creates an instance of String so that charAt(0) will
work.The String object exists only for one statement before it’s destroyed
check this
The instanceof operator returns false because a temporary object is
created only when a value is read. Because instanceof doesn’t actually read
anything, no temporary objects are created, and it tells us the ­values aren’t
instances of primitive wrapper types. You can create primitive wrapper
types manually
For me the confusion caused by
"str".__proto__ // #1
=> String
So "str" istanceof String should return true because how istanceof works as below:
"str".__proto__ == String.prototype // #2
=> true
Results of expression #1 and #2 conflict each other, so there should be one of them wrong.
#1 is wrong
I figure out that it caused by the __proto__ is non standard property, so use the standard one:Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Now there's no confusion between expression #2 and #3
Or you can just make your own function like so:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
usage:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
These should both return true.

Numbers in javascript clarification? [duplicate]

Just curious:
4 instanceof Number => false
new Number(4) instanceof Number => true?
Why is this? Same with strings:
'some string' instanceof String returns false
new String('some string') instanceof String => true
String('some string') instanceof String also returns false
('some string').toString instanceof String also 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 Constructor is the same as Constructor.prototype.isPrototypeOf(value) and both check the [[Prototype]]-chain of value for 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) and new String(value) do different things: If you call the constructor functions of the built-in types without using the new operator, they try to convert ('cast') the argument to the specific type. If you use the new operator, they create a wrapper object.
new String(value) is roughly equivalent to Object(String(value)), which behaves the same way as new 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 null is a primitive value of type Null. This means that the result of the typeof operator 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 instanceof fails (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:
function typeOf(value) {
var type = typeof value;
switch(type) {
case 'object':
return value === null ? 'null' : Object.prototype.toString.call(value).
match(/^\[object (.*)\]$/)[1]
case 'function':
return 'Function';
default:
return type;
}
}
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 (eg new 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.
You may try to evaluate:
>>> typeof("a")
"string"
>>> typeof(new String("a"))
"object"
>>> typeof(4)
"number"
>>> typeof(new Number(4))
"object"
As stated in Christoph's answer, string and number literals are not the same as String and Number objects. If you use any of the String or Number methods on the literal, say
'a string literal'.length
The literal is temporarily converted to an object, the method is invoked and the object is discarded.
Literals have some distinct advantages over objects.
//false, two different objects with the same value
alert( new String('string') == new String('string') );
//true, identical literals
alert( 'string' == 'string' );
Always use literals to avoid unexpected behaviour!
You can use Number() and String() to typecast if you need to:
//true
alert( Number('5') === 5 )
//false
alert( '5' === 5 )
In the case of primitive numbers, the isNaN method could also help you.
This is a nuance of Javascript which I've found catches some out. The instanceof of operator will always result in false if the LHS is not an object type.
Note that new String('Hello World') does not result in a string type but is an object. The new operator always results in an object. I see this sort of thing:
function fnX(value)
{
if (typeof value == 'string')
{
//Do stuff
}
}
fnX(new String('Hello World'));
The expectation is that "Do Stuff" will happen but it doesn't because the typeof the value is object.

[] is an instance of Array but "" isn't of String [duplicate]

"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
// the tests against Object really don't make sense
Array literals and Object literals match...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Why don't all of them? Or, why don't they all not?
And, what are they an instance of, then?
It's the same in FF3, IE7, Opera, and Chrome. So, at least it's consistent.
Primitives are a different kind of type than objects created from within Javascript. From the Mozilla API docs:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
I can't find any way to construct primitive types with code, perhaps it's not possible. This is probably why people use typeof "foo" === "string" instead of instanceof.
An easy way to remember things like this is asking yourself "I wonder what would be sane and easy to learn"? Whatever the answer is, Javascript does the other thing.
I use:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Because in JavaScript strings can be literals or objects.
In JavaScript everything is an object (or may at least be treated as an object), except primitives (booleans, null, numbers, strings and the value undefined (and symbol in ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
As you can see objects, arrays and the value null are all considered objects (null is a reference to an object which doesn't exist). Functions are distinguished because they are a special type of callable objects. However they are still objects.
On the other hand the literals true, 0, "" and undefined are not objects. They are primitive values in JavaScript. However booleans, numbers and strings also have constructors Boolean, Number and String respectively which wrap their respective primitives to provide added functionality:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
As you can see when primitive values are wrapped within the Boolean, Number and String constructors respectively they become objects. The instanceof operator only works for objects (which is why it returns false for primitive values):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
As you can see both typeof and instanceof are insufficient to test whether a value is a boolean, a number or a string - typeof only works for primitive booleans, numbers and strings; and instanceof doesn't work for primitive booleans, numbers and strings.
Fortunately there's a simple solution to this problem. The default implementation of toString (i.e. as it's natively defined on Object.prototype.toString) returns the internal [[Class]] property of both primitive values and objects:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
The internal [[Class]] property of a value is much more useful than the typeof the value. We can use Object.prototype.toString to create our own (more useful) version of the typeof operator as follows:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
Hope this article helped. To know more about the differences between primitives and wrapped objects read the following blog post: The Secret Life of JavaScript Primitives
You can use constructor property:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
you can use this, it will work for both case as
var text="foo"; // typeof will work
String text= new String("foo"); // instanceof will work
This is defined in the ECMAScript specification Section 7.3.19 Step 3: If Type(O) is not Object, return false.
In other word, if the Obj in Obj instanceof Callable is not an object, the instanceof will short-circuit to false directly.
I believe I have come up with a viable solution:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
The primitive wrapper types are reference types that are automatically created behind the scenes whenever strings, num­bers, or Booleans
are read.For example :
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
This is what happens behind the scenes:
// what the JavaScript engine does
var name = "foo";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);
Because the second line uses a string (a primitive) like an object,
the JavaScript engine creates an instance of String so that charAt(0) will
work.The String object exists only for one statement before it’s destroyed
check this
The instanceof operator returns false because a temporary object is
created only when a value is read. Because instanceof doesn’t actually read
anything, no temporary objects are created, and it tells us the ­values aren’t
instances of primitive wrapper types. You can create primitive wrapper
types manually
For me the confusion caused by
"str".__proto__ // #1
=> String
So "str" istanceof String should return true because how istanceof works as below:
"str".__proto__ == String.prototype // #2
=> true
Results of expression #1 and #2 conflict each other, so there should be one of them wrong.
#1 is wrong
I figure out that it caused by the __proto__ is non standard property, so use the standard one:Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Now there's no confusion between expression #2 and #3
Or you can just make your own function like so:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
usage:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
These should both return true.

"instanceof" of a String object vs that of "string" literals [duplicate]

"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
// the tests against Object really don't make sense
Array literals and Object literals match...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Why don't all of them? Or, why don't they all not?
And, what are they an instance of, then?
It's the same in FF3, IE7, Opera, and Chrome. So, at least it's consistent.
Primitives are a different kind of type than objects created from within Javascript. From the Mozilla API docs:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
I can't find any way to construct primitive types with code, perhaps it's not possible. This is probably why people use typeof "foo" === "string" instead of instanceof.
An easy way to remember things like this is asking yourself "I wonder what would be sane and easy to learn"? Whatever the answer is, Javascript does the other thing.
I use:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Because in JavaScript strings can be literals or objects.
In JavaScript everything is an object (or may at least be treated as an object), except primitives (booleans, null, numbers, strings and the value undefined (and symbol in ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
As you can see objects, arrays and the value null are all considered objects (null is a reference to an object which doesn't exist). Functions are distinguished because they are a special type of callable objects. However they are still objects.
On the other hand the literals true, 0, "" and undefined are not objects. They are primitive values in JavaScript. However booleans, numbers and strings also have constructors Boolean, Number and String respectively which wrap their respective primitives to provide added functionality:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
As you can see when primitive values are wrapped within the Boolean, Number and String constructors respectively they become objects. The instanceof operator only works for objects (which is why it returns false for primitive values):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
As you can see both typeof and instanceof are insufficient to test whether a value is a boolean, a number or a string - typeof only works for primitive booleans, numbers and strings; and instanceof doesn't work for primitive booleans, numbers and strings.
Fortunately there's a simple solution to this problem. The default implementation of toString (i.e. as it's natively defined on Object.prototype.toString) returns the internal [[Class]] property of both primitive values and objects:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
The internal [[Class]] property of a value is much more useful than the typeof the value. We can use Object.prototype.toString to create our own (more useful) version of the typeof operator as follows:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
Hope this article helped. To know more about the differences between primitives and wrapped objects read the following blog post: The Secret Life of JavaScript Primitives
You can use constructor property:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
you can use this, it will work for both case as
var text="foo"; // typeof will work
String text= new String("foo"); // instanceof will work
This is defined in the ECMAScript specification Section 7.3.19 Step 3: If Type(O) is not Object, return false.
In other word, if the Obj in Obj instanceof Callable is not an object, the instanceof will short-circuit to false directly.
I believe I have come up with a viable solution:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
The primitive wrapper types are reference types that are automatically created behind the scenes whenever strings, num­bers, or Booleans
are read.For example :
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
This is what happens behind the scenes:
// what the JavaScript engine does
var name = "foo";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);
Because the second line uses a string (a primitive) like an object,
the JavaScript engine creates an instance of String so that charAt(0) will
work.The String object exists only for one statement before it’s destroyed
check this
The instanceof operator returns false because a temporary object is
created only when a value is read. Because instanceof doesn’t actually read
anything, no temporary objects are created, and it tells us the ­values aren’t
instances of primitive wrapper types. You can create primitive wrapper
types manually
For me the confusion caused by
"str".__proto__ // #1
=> String
So "str" istanceof String should return true because how istanceof works as below:
"str".__proto__ == String.prototype // #2
=> true
Results of expression #1 and #2 conflict each other, so there should be one of them wrong.
#1 is wrong
I figure out that it caused by the __proto__ is non standard property, so use the standard one:Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Now there's no confusion between expression #2 and #3
Or you can just make your own function like so:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
usage:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
These should both return true.

Why does instanceof return false for some literals?

"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
// the tests against Object really don't make sense
Array literals and Object literals match...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Why don't all of them? Or, why don't they all not?
And, what are they an instance of, then?
It's the same in FF3, IE7, Opera, and Chrome. So, at least it's consistent.
Primitives are a different kind of type than objects created from within Javascript. From the Mozilla API docs:
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
I can't find any way to construct primitive types with code, perhaps it's not possible. This is probably why people use typeof "foo" === "string" instead of instanceof.
An easy way to remember things like this is asking yourself "I wonder what would be sane and easy to learn"? Whatever the answer is, Javascript does the other thing.
I use:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Because in JavaScript strings can be literals or objects.
In JavaScript everything is an object (or may at least be treated as an object), except primitives (booleans, null, numbers, strings and the value undefined (and symbol in ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
As you can see objects, arrays and the value null are all considered objects (null is a reference to an object which doesn't exist). Functions are distinguished because they are a special type of callable objects. However they are still objects.
On the other hand the literals true, 0, "" and undefined are not objects. They are primitive values in JavaScript. However booleans, numbers and strings also have constructors Boolean, Number and String respectively which wrap their respective primitives to provide added functionality:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
As you can see when primitive values are wrapped within the Boolean, Number and String constructors respectively they become objects. The instanceof operator only works for objects (which is why it returns false for primitive values):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
As you can see both typeof and instanceof are insufficient to test whether a value is a boolean, a number or a string - typeof only works for primitive booleans, numbers and strings; and instanceof doesn't work for primitive booleans, numbers and strings.
Fortunately there's a simple solution to this problem. The default implementation of toString (i.e. as it's natively defined on Object.prototype.toString) returns the internal [[Class]] property of both primitive values and objects:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
The internal [[Class]] property of a value is much more useful than the typeof the value. We can use Object.prototype.toString to create our own (more useful) version of the typeof operator as follows:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
Hope this article helped. To know more about the differences between primitives and wrapped objects read the following blog post: The Secret Life of JavaScript Primitives
You can use constructor property:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
you can use this, it will work for both case as
var text="foo"; // typeof will work
String text= new String("foo"); // instanceof will work
This is defined in the ECMAScript specification Section 7.3.19 Step 3: If Type(O) is not Object, return false.
In other word, if the Obj in Obj instanceof Callable is not an object, the instanceof will short-circuit to false directly.
I believe I have come up with a viable solution:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
The primitive wrapper types are reference types that are automatically created behind the scenes whenever strings, num­bers, or Booleans
are read.For example :
var name = "foo";
var firstChar = name.charAt(0);
console.log(firstChar);
This is what happens behind the scenes:
// what the JavaScript engine does
var name = "foo";
var temp = new String(name);
var firstChar = temp.charAt(0);
temp = null;
console.log(firstChar);
Because the second line uses a string (a primitive) like an object,
the JavaScript engine creates an instance of String so that charAt(0) will
work.The String object exists only for one statement before it’s destroyed
check this
The instanceof operator returns false because a temporary object is
created only when a value is read. Because instanceof doesn’t actually read
anything, no temporary objects are created, and it tells us the ­values aren’t
instances of primitive wrapper types. You can create primitive wrapper
types manually
For me the confusion caused by
"str".__proto__ // #1
=> String
So "str" istanceof String should return true because how istanceof works as below:
"str".__proto__ == String.prototype // #2
=> true
Results of expression #1 and #2 conflict each other, so there should be one of them wrong.
#1 is wrong
I figure out that it caused by the __proto__ is non standard property, so use the standard one:Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Now there's no confusion between expression #2 and #3
Or you can just make your own function like so:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
usage:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
These should both return true.

Categories