This is basically the same as Learning Array.prototype and calculating its length.
String.prototype
is a string, according to the specification, §15.5.4, Properties of the String Prototype Object:
The String prototype object is itself a String object (its [[Class]]
is "String"
) whose value is an empty String.
The value of the [[Prototype]]
internal property of the String prototype object is the standard built-in Object prototype object (15.2.4).
But it is not an instance of the constructor function String
.
instanceof
works by comparing the prototype of the instance with the prototype
property of the constructor function (§15.3.5.3), i.e.
Object.getPrototypeOf(String.prototype) === String.prototype
So, you are testing whether String.prototype
is it's own prototype, which is of course false
. The prototype of String.prototype
is, as mentioned in the specification, Object.prototype
.
A word regarding the first example:
> js> "".__proto__
(new String(""))
You have to keep in mind that the console (or RELP) uses some heuristic to format and present values. For example it might read the constructor
property of the object to determine what "kind" of value it is and format the output accordingly. That's what the Chrome console is doing:
var str = new String('foo');
str instanceof String
=> true
console.dir(str);
=> String
var obj = {};
console.dir(obj);
=> Object // looks good
obj.constructor = String;
=> console.dir(obj);
String // uhm what?
obj instanceof String
=> false
It happens that every prototype object has a constructor
property, which points back to the function it is the prototype object of, i.e.
function Foo() {}
Foo.prototype.constructor === Foo;
=> true
console.dir(Foo.prototype)
=> Foo
So if you log a prototype object, the output might suggest that the object is an instance of the function itself although it isn't, just because of the constructor
property.