Extending core types without modifying prototype

maerics picture maerics · Aug 22, 2011 · Viewed 7.9k times · Source

How does one extend core JavaScript types (String, Date, etc.) without modifying their prototypes? For example, suppose I wanted to make a derived string class with some convenience methods:

function MyString() { }
MyString.prototype = new String();
MyString.prototype.reverse = function() {
  return this.split('').reverse().join('');
};
var s = new MyString("Foobar"); // Hmm, where do we use the argument?
s.reverse();
// Chrome - TypeError: String.prototype.toString is not generic
// Firefox - TypeError: String.prototype.toString called on incompatible Object

The error seems to originate from String base methods, probably "split" in this case, since its methods are being applied to some non-string object. But if we can't apply the to non-string objects then can we really reuse them automatically?

[Edit]

Obviously my attempt is flawed in many ways but I think it demonstrates my intent. After some thinking, it seems that we can't reuse any of the String prototype object's functions without explicitly calling them on a String.

Is it possible to extend core types as such?

Answer

Raynos picture Raynos · Aug 22, 2011

2 years later: mutating anything in global scope is a terrible idea

Original:

There being something "wrong" with extending native prototypes is FUD in ES5 browsers.

Object.defineProperty(String.prototype, "my_method", {
  value: function _my_method() { ... },
  configurable: true,
  enumerable: false,
  writeable: true
});

However if you have to support ES3 browsers then there are problems with people using for ... in loops on strings.

My opinion is that you can change native prototypes and should stop using any poorly written code that breaks