Changing the prototype of the String object
Extending native objects is bad practice. 


When you're expecting nothing, then something shows up. That's natural behavior of prototypes.
Forwards compatibility. The same reason why Object.keys(someObjectInstance) is designed that way instead of someObjectInstance.keys() - because some implementations may already have used keys as a property. So what if ECMAScript 9 wants to use left() and right() for some string operation, your app will break.


For alternatives:


You can create your own functions in a separate namespace, that looks like the native functions. For instance, the native forEach looks like array.forEach(fn). Underscore writes it differently with _.forEach(array,fn).
You can extend native objects. Mileage may vary on this one as some (not sure which, but most) native objects are not subclassable.
You could create "wrapper objects" that just wrap the object into another object, who has methods that operate on the wrapped object. A good example is jQuery which wraps an array of stuff in a "jQuery object" which hosts a myriad of DOM manipulation methods that operate on that set.
Create a custom object that doesn't necessarily extend/inherit/wrap anything. Something like var string = new CustomString('hello world').