Extend a String class in ES6

18,177

Solution 1

In ES6 you can also do it with Object.assign() like this:

Object.assign(String.prototype, {
    something() {
        return this.split(' ').join();
    }
});

You can find more info to the method here.

Or you could use defineProperty (I think that would be better here):

Object.defineProperty(String.prototype, 'something', {
    value() {
        return this.split(' ').join();
    }
});

See the docs here.

See my comment to see when to use defineProperty vs Object.assign().

Solution 2

Your proposal works fine in ES6, is there something wrong with it?

If you want to actually extend String, instead of just adding a method to String itself, and get that warm ES6 feeling, you could try:

class MyString extends String {
    something() { return this.split(' ').join(''); }
}

However, you are going to quickly run into limitations on extending built-in classes. Chances are you will see the dreaded

TypeError: String.prototype.toString is not generic

error message (this is from babel-node).

Share:
18,177

Related videos on Youtube

ritz078
Author by

ritz078

Updated on July 03, 2022

Comments

  • ritz078
    ritz078 almost 2 years

    I can write the following in ES5:

    String.prototype.something=function(){
      return this.split(' ').join('');
    };
    

    How do I do the same thing in ES6 using the new features?

    I know that this is also a valid ES6. I want to know whether there's any other way of implementing such functions in ES6 which is shorter?
    The above function is just an example.

    • Qantas 94 Heavy
      Qantas 94 Heavy about 9 years
      Is the example code your actual use case or are you talking about extending String.prototype in general?
    • Felix Kling
      Felix Kling about 9 years
      All ES5 code is also valid ES6 code. So you can just use the same code.
    • ritz078
      ritz078 about 9 years
      @Qantas94Heavy I was talking for a general case.
    • KyleMit
      KyleMit almost 5 years
      Might be worth noting that you can't update to arrow functions as the value for this is provided by their lexical scope.
    • broofa
      broofa over 4 years
      It's worth noting that extending native objects like this, while not strictly prohibited, is pretty much never a good idea. See stackoverflow.com/questions/14034180/… for more. (tl;dr: Changes the behavior of the object in subtle and not-so-subtle ways that may break other code.)
    • jehon
      jehon over 3 years
      Note that strings are immutable
  • Admin
    Admin about 9 years
    What is the difference? What is the advantage? Why would he want to do this anyway instead of using defineProperty?
  • AWolf
    AWolf about 9 years
    Yes, you're right defineProperty would be better here. See this blog post. Especially the conclusion summarizes it pretty well. I'll add it to my answer in a minute.
  • Qantas 94 Heavy
    Qantas 94 Heavy about 9 years
    I think this is an issue with babel (which can't be fixed easily AFAIK), in "proper" implementations with real subclassing support this should work properly.
  • Qantas 94 Heavy
    Qantas 94 Heavy about 9 years
    Isn't defineProperty ES5 code? I really don't see how ES6 provides a better method of extending String than that (apart from subclassing).
  • ritz078
    ritz078 about 9 years
    So that means that es5 is still the best method to implement such functions.
  • ritz078
    ritz078 about 9 years
    It works fine in es6 but just wanted to know if any shorter way is available in es6.