I'm trying to understand how JavaScript's prototype-based inheritance works. I was expecting the below outputs would evaluate as true
. Why is this?
var myStr = "Sample";
String.prototype.isPrototypeOf(myStr); // false
Object.prototype.isPrototypeOf(myStr); // false
The prototype is a property available with all JavaScript objects. The prototype property allows you to add new properties and methods to strings.
Every object in JavaScript has a built-in property, which is called its prototype. The prototype is itself an object, so the prototype will have its own prototype, making what's called a prototype chain.
Prototypes are a special type of object and exist as a property on function-objects. When we try to access a key on a function-object, JavaScript will look at its prototype property to see if it's there. If not it will go up the prototype-chain to try to find it.
Conceptually, all objects have a prototype (NOT A PROTOTYPE PROPERTY). Internally, JavaScript names an object's prototype as [[Prototype]]. There are two approaches to get any object (including non-function object)'s [[prototype]]: the Object. getPrototypeOf() method and the __proto__ property.
JavaScript has both primitive strings and string objects. What you've written there is a primitive string. The Object.prototype.isPrototypeOf
method always returns false
for any primitive, so your results make sense.
If you used a string object, you'd get true
:
var myStr = new String("Sample");
console.log(String.prototype.isPrototypeOf(myStr)); // true
console.log(Object.prototype.isPrototypeOf(myStr)); // true
You're probably wondering: If it's a primitive, then why can I call methods on it that are defined on String.prototype
?
The answer is that the specification defines that if you use a property accessor on a primitive string, a temporary string object with an equivalent character sequence is created (with String.prototype
as its prototype), and the property is then read from that temporary object. (The same is done with numbers.)
We can prove that the temporary object is created by adding a method to String.prototype
that returns that object (just for the purposes of illustration):
Object.defineProperty(String.prototype, "foo", {
value: function() {
return this;
}
});
var primitive = "string";
var object = primitive.foo();
console.log(primitive === object); // false
console.log(primitive == object); // true
console.log(String.prototype.isPrototypeOf(primitive)); // false
console.log(String.prototype.isPrototypeOf(object)); // true
This is because the string primitives are not string objects. If you want the above code to work, the string should be constructed via the String
class, as in:
var myStr = new String("Sample");
String.prototype.isPrototypeOf(myStr); // true
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With