4

Is it possible to add methods to a String instance, for example

x = "123"
x.method = function() { console.log("test") }

x.method()
9
  • If you change x = "123" by x = new String("123") yeah, but it is not good practice. Commented Mar 29, 2013 at 22:04
  • Have you consider using the prototype property ? w3schools.com/jsref/jsref_prototype_math.asp Commented Mar 29, 2013 at 22:05
  • You could also add it to String.prototype if you want the function on all your strings, but like others said, it's not a good practice to modify native object prototypes. String.prototype.method = function () { console.log(this); } Commented Mar 29, 2013 at 22:06
  • @lemil77 Please don't suggest w3schools.com.Have a look at this : en.wikipedia.org/wiki/W3Schools. Commented Mar 29, 2013 at 22:08
  • @FabrícioMatté: There's nothing "not good practice" about extending an instance. There is some argument against extending built-in prototypes (though I've never seen any problem extending String.prototype), but not individual instances. Commented Mar 29, 2013 at 22:18

3 Answers 3

4

Yes, you can do it. You have to first take the string primitive and make it a string instance, though:

x = new String("123");
x.method = function() { console.log("test") };

x.method();

JavaScript has both string primitives and string instances. In your original code, when you wrote:

x.method = ...;

...the string primitive was retrieved from the variable x and promoted to a string instance, to which you added the method, but since the string instance was never stored back to the x variable, the method wasn't there when you tried to call it. (Yes, this is counter-intuitive.)

By using new String(...) in the above, I actually get the string instance and store it in x. Then, since it's a proper object, I can add properties to it.

You can also add methods to String.prototype, like this:

String.prototype.capitalize = function() {
    return this.substring(0, 1).toUpperCase() + this.substring(1);
};

console.log("testing".capitalize()); // "Testing"

Some feel this is bad practice. Others say it's exactly why we have prototypical inheritance, so we can use the prototype to enhance things. While I've never seen any problem from people enhancing String.prototype, I have seem problems when people enhance Array.prototype (because people insist on misuing for-in) and Object.prototype.

Sign up to request clarification or add additional context in comments.

Comments

3

Strings and numbers are autoboxed primitives, meaning that when you perform OO operations on them, they are cast as "String" and "Number" classes but then are immediately unboxed.

Your code evaluates to:

x = "123"
(new String(x)).method = function() { console.log("test") }

(new String(x)).method() // Error

Your second call is failing because you are dealing with an entirely different String object. As T.J. stated, you can get around this by making x a String object, but this is not a common or recommended practice.

You can extend all strings by adding the method to String.prototype:

x = "123"
String.prototype.method = function() { console.log("test") }

x.method()

This call evaluates the same way as (new String(x)).method() but since that method exists in the prototype, it will get called.

3 Comments

And, how to access to string from the function?
@e-info128 You can use this inside the method, which will be the boxed String rather than the primitive string, but most operations would work the same. E.g. String.prototype.parseInt = function () { return parseInt(this); }
If you need the primitive string, you could do this.toString() inside the function.
1

You could define new properties using ECMA5

Object.defineProperty(String.prototype, "test", {
value: function test() { console.log('test:',this) },
  configurable: true,
  enumerable: false,
  writeable: true
});

See the complete answer: Extending core types without modifying prototype

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.