问题
"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
// 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.
Missed a few.
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
回答1:
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.
回答2:
I use:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Because in JavaScript strings can be literals or objects.
回答3:
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
回答4:
You can use constructor property:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
回答5:
typeof(text) === 'string' || text instanceof String;
you can use this, it will work for both case as
var text="foo";
// typeof will workString text= new String("foo");
// instanceof will work
回答6:
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.
回答7:
I believe I have come up with a viable solution:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
回答8:
https://www.npmjs.com/package/typeof
Returns a string-representation of instanceof
(the constructors name)
function instanceOf(object) {
var type = typeof object
if (type === 'undefined') {
return 'undefined'
}
if (object) {
type = object.constructor.name
} else if (type === 'object') {
type = Object.prototype.toString.call(object).slice(8, -1)
}
return type.toLowerCase()
}
instanceOf(false) // "boolean"
instanceOf(new Promise(() => {})) // "promise"
instanceOf(null) // "null"
instanceOf(undefined) // "undefined"
instanceOf(1) // "number"
instanceOf(() => {}) // "function"
instanceOf([]) // "array"
回答9:
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
回答10:
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.
来源:https://stackoverflow.com/questions/12254658/is-an-instance-of-array-but-isnt-of-string