18

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.

brasofilo
  • 25,496
  • 15
  • 91
  • 179
ritz078
  • 2,193
  • 3
  • 22
  • 24
  • 1
    Is the example code your actual use case or are you talking about extending `String.prototype` in general? – Qantas 94 Heavy May 15 '15 at 11:57
  • 1
    All ES5 code is also valid ES6 code. So you can just use the same code. – Felix Kling May 15 '15 at 13:47
  • @Qantas94Heavy I was talking for a general case. – ritz078 May 15 '15 at 14:50
  • 1
    Might be worth noting that you **can't update to arrow functions** as the value for `this` is provided by their lexical scope. – KyleMit Jun 30 '19 at 21:37
  • It's worth noting that extending native objects like this, while not strictly prohibited, is pretty much never a good idea. See https://stackoverflow.com/questions/14034180/why-is-extending-native-objects-a-bad-practice for more. (tl;dr: Changes the behavior of the object in subtle and not-so-subtle ways that may break other code.) – broofa Dec 17 '19 at 16:59
  • Note that strings are immutable – jehon Dec 24 '20 at 14:47

2 Answers2

29

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().

AWolf
  • 8,770
  • 5
  • 33
  • 39
  • 1
    What is the difference? What is the advantage? Why would he want to do this anyway instead of using `defineProperty`? –  May 15 '15 at 12:25
  • Yes, you're right defineProperty would be better here. See this [blog post](http://www.2ality.com/2012/08/property-definition-assignment.html). Especially the conclusion summarizes it pretty well. I'll add it to my answer in a minute. – AWolf May 15 '15 at 12:41
  • Isn't `defineProperty` ES5 code? I really don't see how ES6 provides a better method of extending `String` than that (apart from subclassing). – Qantas 94 Heavy May 15 '15 at 14:52
  • So that means that es5 is still the best method to implement such functions. – ritz078 May 15 '15 at 14:57
9

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).

  • 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 May 15 '15 at 14:50
  • It works fine in es6 but just wanted to know if any shorter way is available in es6. – ritz078 May 15 '15 at 15:01