Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object and String prototypes are not prototypes of defined strings?

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
like image 749
user3197944 Avatar asked Dec 13 '16 17:12

user3197944


People also ask

What is the prototype of String?

The prototype is a property available with all JavaScript objects. The prototype property allows you to add new properties and methods to strings.

Does object have prototype?

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.

What is difference between object and prototype in JavaScript?

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.

Do objects have prototype property?

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.


2 Answers

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
like image 157
T.J. Crowder Avatar answered Sep 29 '22 03:09

T.J. Crowder


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
like image 20
laurent Avatar answered Sep 29 '22 03:09

laurent