CrackerKSR
CrackerKSR

Reputation: 1877

What is the use of the prototype property with string in JavaScript?

How prototype property can be used with string variable in JavaScript. There is topic in our textbook which shows prototype as property but lack of explanations and confusing about it's usage

Take this code example for reference.

let x = 'stackoverflow';
console.log(x.prototype) // gives list of functions

console.log(x.prototype.toLowerCase())) // gives error

Upvotes: 0

Views: 96

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074238

The String.prototype object is what gives strings their methods (even though most strings you deal with are primitives, not objects). If there weren't a String.prototype.toLowerCase function, then "FOO".toLowerCase() wouldn't work. This is the fundamental prototypical nature of JavaScript (but a bit confusing, with most strings being primitives; more on that below¹).

One use of String.prototype in userland code is to add methods to strings:

Object.defineProperty(String.prototype, "initialCaps", {
    writable: true,
    configurable: true,
    value() {
        return this.charAt(0).toUpperCase() + this.slice(1);
    }
});


console.log("testing".initialCaps());

In general, extending built-in prototypes like that is best avoided in library or framework code because of the possibility of conflicts with other libraries, etc. It's generally okay in your own app or web page code, though.

A couple of best practices rules if you do that:

  • Make sure the methods you add are non-enumerable by using Object.defineProperty as in the example above. don't just do String.prototype.initialCaps = function() { /*...*/ };, that creates an enumerable property. Because the example above doesn't say enumerable: true, the property is non-enumerable by default. (Builtin methods are typically writable and configurable, though.)

  • Use names that are unlikely to be used by future additions to JavaScript, so they don't conflict later if things are added.

  • Never extend Object.prototype if you're using any third-party code. You may break that code.

  • Be cautious extending Array.prototype if you're using any third-party code. You may break that code.

With thorough testing you could of course go against any of those, but...


¹ About the primitive string vs. string object thing:

"example" creates a primitive string. Primitives aren't objects (in theory) and so they don't have properties or methods (in theory). But most primitives have an object constructor associated with them: String is the case of strings, Number for numbers, etc. (null and undefined do not have associated constructors.) If you try to use a property or method on a primitive with an associated constructor function, in theory the JavaScript engine creates an object equivalent of that primitive and then does the property/method lookup on that object. Since that object's prototype is the object from the prototype property on its constructor, it gets properties and methods from that object. If it's a method, the JavaScript engine calls the method with the original primitive value as this. (In loose mode, it'll get converted to object so this is an object within the call; in strict mode, though, this can be a primitive, and is in the case of method calls on a primitive.)

All of which is a long way of explaining that "example".toLowerCase() ends up calling String.prototype.toLowerCase with this set to "example".

I said "in theory" a couple of times above because JavaScript engines do a lot of optimization. As long as they behave in line with what the spec says, they don't have to literally do what the spec says. You can be fairly sure that when you do "example".length or "example".toLowerCase() (for instance), no modern JavaScript engine actually creates a String object under the covers for any of the built-in object properties/methods. (It may have to if you've added any, if your additions are in loose mode. One of many reasons to always use strict mode.)

Upvotes: 2

Related Questions