86

I'd like to be able to say something like this in javascript :

   "a".distance("b")

How can I add my own distance function to the string class?

2
  • What is it called when someone does this. Is that considered monkey patching or something else sine you are only adding a new method? Commented Aug 9, 2016 at 15:53
  • @still_dreaming_1 It's called extending: stackoverflow.com/questions/3781373/… Commented Nov 4, 2016 at 19:50

6 Answers 6

161

You can extend the String prototype;

String.prototype.distance = function (char) {
    var index = this.indexOf(char);

    if (index === -1) {
        alert(char + " does not appear in " + this);
    } else {
        alert(char + " is " + (this.length - index) + " characters from the end of the string!");
    }
};

... and use it like this;

"Hello".distance("H");

See a JSFiddle here.

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

5 Comments

FYI.. use this to get the string this function is called on
Actually, for me, this returns an object like String {0: "t", 1: "e", 2: "s", 3: "t", length: 4, [[PrimitiveValue]]: "test"}. To work with the actual text, I had to call this.toString()
is there any way to write "String.prototype.distance = function (char) {}" in ECMA script way?
Extending native JavaScript objects is generally a bad practice. See stackoverflow.com/questions/14034180/…
how about an array? Array.prototype.myFunc = function(a) and [/*...*/].myFunc(5) don't work
22
String.prototype.distance = function( arg ) {
    // code
};

Comments

19

Minimal example:

No ones mentioned valueOf.

==================================================

String.prototype.
OPERATES_ON_COPY_OF_STRING = function ( 
    ARGUMENT 
){

    //:Get primitive copy of string:
    var str = this.valueOf();

    //:Append Characters To End:
    str = str + ARGUMENT;

    //:Return modified copy:
    return( str );
};

var a = "[Whatever]";
var b = a.OPERATES_ON_COPY_OF_STRING("[Hi]");
console.log( a ); //: [Whatever]
console.log( b ); //: [Whatever][Hi]

==================================================

From my research into it, there is no way to edit the string in place.

Even if you use a string object instead of a string primitive.

Below does NOT work and get's really weird results in the debugger.

==================================================

String.prototype.
EDIT_IN_PLACE_DOES_NOT_WORK = function ( 
    ARGUMENT 
){

    //:Get string object:
    var str = this;

    //:Append Characters To End:
    var LN = str.length;
    for( var i = 0; i < ARGUMENT.length; i++){
        str[LN+i] = ARGUMENT[ i ];
    };

};

var c = new String( "[Hello]" );
console.log( c );
c.EDIT_IN_PLACE_DOES_NOT_WORK("[World]");
console.log( c );

==================================================

3 Comments

This is exactly what I was searching for.
While the accepted answer, answers the original question this is a stronger overall general answer. I do have to ask why return(str) vs return str?
I was creating a new method for string class, something like String.prototype.toJadeCase(). And this answer helped me achieve that.
13

after years (and ES6) … we have a new option how to do this:

Object.defineProperty( String.prototype, 'distance', {
	value: function ( param )
	{
		// your code …
		return 'counting distance between ' + this + ' and ' + param;
	}
} );

// ... and use it like this:
const result = "a".distance( "b" );
console.log(result);

2 Comments

this only defines a common property for all strings. what if i want to add a different function instance to each string instance?
@Michael yes, this example add property only for String(). But it's possible to add property into all objects by using Window.prototype instead of String.prototype.
8

You could do this:

String.prototype.distance = function (){ 
    //your code 
}

1 Comment

That's a syntax error (you commented out your closing curly brace) :D
4

Using prototype to add you own function to string is called a prototype I created small JavaScript code that can select elements and change its innerHTML

var dom; //you can replce this to be $ just like jQuery
dom = function(elm) {
if(typeof elm === "object") {
   // already done example 
   //typeof document.getElementById('id') will be object
   return [elm];
 } else {
    return document.querySelectorAll(elm);
 }
} // Returns elements by all css selector eg
// .class #id id p id > p id ~ p in short any css selectors 
 Object.prototype.text = function(txt) {  //object prototype as NodeList returned would be object or maybe displayed as [Object NodeList]
     var i = 0; //loop through the elements 
     for(i; i < this.length; i++) {
        this[i].innerHTML = txt;
      }
 // in this function this refers to object that this function is passed on
 };
 dom('.classh').text('Changed for elements with classh');
 dom('#heading').text('Changed for elements with id heading'); //examples

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.