What do we know about v?
The expressions tell us two things about
v: It is an object, but it is not an instance of
Object.
v is an object
The first two expressions use the
typeof operator to ascertain that
v is an object. The second expression is only needed because
typeof has a bug and returns
"object" for null
[1].
Thus,
v will have all of the characteristics of an object.
Remember that JavaScript has two kinds of values: primitives and objects [2]. Primitives are read-only – you can try to create or change properties, but those operations have no effect:
> var str = "abc";
> str.foo = 123;
123
> str.foo
undefined
> str.length
3
> str.length = 1;
> str.length
3
Primitives are also compared
by value – the contents of a value determine whether it is equal to another value of the same type:
> "abc" === "abc"
true
In contrast, objects are mutable and compared
by reference. Every object has its own identity. Even if they have the same content, two objects are only equal if they have the same identity:
> new String("abc") === new String("abc")
false
> {} === {}
false
> var obj = {};
> obj === obj
true
v is not an instance of Object
The third expression tells us that
v is not an instance of
Object. But what does that mean? To check whether
value instanceof type
holds, the
instanceof operator looks at
type.prototype and checks whether it is in the prototype chain of
value. That is, if we were to implement
instanceof ourselves, it would look like this (minus some error checks, such as for
type being null):
function myInstanceof(value, type) {
return type.prototype.isPrototypeOf(value);
}
Finding an object without a prototype
We must therefore find an object that does not have
Object.prototype in its prototype chain. None of the built-in types fit the bill:
> Object.prototype.isPrototypeOf({})
true
> Object.prototype.isPrototypeOf([])
true
> Object.prototype.isPrototypeOf(/abc/)
true
We can, however, use
Object.create to create on object that does not have any prototype, not even
Object.prototype:
> var obj = Object.create(null)
undefined
> Object.getPrototypeOf(obj)
null
> Object.prototype.isPrototypeOf(obj)
false
obj does not have standard methods such as
toString, but it is still an object, with properties and all the usual features.
We have thus found our
v:
> obj instanceof Object
false
> typeof obj
'object'
Another solution. Given that prototype chains must end somewhere,
Object.prototype does not have a prototype, either:
> Object.prototype instanceof Object
false
> typeof Object.prototype
'object'
Kudos to @michaelasmith for this alternative answer.
The objects in the
prototype properties of other built-in types do have prototypes:
> Object.getPrototypeOf(Date.prototype)
{}