81

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?

Herohtar
  • 5,347
  • 4
  • 31
  • 41
will
  • 3,103
  • 4
  • 25
  • 30
  • What is it called when someone does this. Is that considered monkey patching or something else sine you are only adding a new method? – still_dreaming_1 Aug 09 '16 at 15:53
  • @still_dreaming_1 It's called extending: http://stackoverflow.com/questions/3781373/javascript-what-are-extend-and-prototype-used-for – spectre-d Nov 04 '16 at 19:50

6 Answers6

152

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.

Matt
  • 74,352
  • 26
  • 153
  • 180
  • 44
    FYI.. use `this` to get the string this function is called on – Brian Low Jul 29 '12 at 05:49
  • 5
    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()` – Wesley Smith Nov 10 '15 at 07:11
  • 1
    is there any way to write "String.prototype.distance = function (char) {}" in ECMA script way? – Biswajit Maji Oct 04 '16 at 04:05
  • 5
    Extending native JavaScript objects is generally a bad practice. See http://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice – Chris Halcrow May 05 '17 at 02:35
22
String.prototype.distance = function( arg ) {
    // code
};
Will
  • 19,661
  • 7
  • 47
  • 48
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 );

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

KANJICODER
  • 3,611
  • 30
  • 17
11

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);
iiic
  • 1,366
  • 2
  • 15
  • 23
  • this only defines a common property for all strings. what if i want to add a different function instance to each string instance? – Michael May 30 '22 at 18:13
8

You could do this:

String.prototype.distance = function (){ 
    //your code 
}
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
JAiro
  • 5,914
  • 2
  • 22
  • 21
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
JavaScript
  • 41
  • 1