扩展核心类型而无需修改原型

mae*_*ics 18 javascript prototypal-inheritance

如何在不修改原型的情况下扩展核心JavaScript类型(String,Date等)?例如,假设我想用一些方便的方法创建一个派生的字符串类:

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
Run Code Online (Sandbox Code Playgroud)

该错误似乎源自String基本方法,在这种情况下可能是"拆分",因为它的方法正在应用于某些非字符串对象.但是如果我们不能应用非字符串对象那么我们真的可以自动重用它们吗?

[编辑]

显然,我的尝试在很多方面存在缺陷,但我认为这证明了我的意图.经过一番思考后,似乎我们不能重用任何String原型对象的函数而不在String上显式调用它们.

是否可以扩展核心类型?

Ray*_*nos 17

2年后:在全球范围内改变任何东西都是一个糟糕的主意

原版的:

ES5浏览器中的FUD是扩展原生原型的"错误".

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

但是,如果您必须支持ES3浏览器,那么人们for ... in在字符串上使用循环时会出现问题.

我的观点是你可以改变原生原型,并且应该停止使用任何破坏的代码

  • 这不是最好的主意.A.这不回答*问题*B.如果你扩展原生对象的原型,那么你的代码就是"破解不良的代码".覆盖原生方法是最糟糕的想法,我已经遇到了这个问题,不要犯同样的错误.如果其他项目不依赖于您的项目,那么它足够安全,但是一旦您发布代码,它就会污染新的命名空间.这对于全局变量不好的原因是不好的. (2认同)
  • @Raynos为什么改变全球范围是一个可怕的想法?你能帮我理解吗?我看到很多人说这是一个坏主意,它留下了更多问题而不是答案的空间,或者有时候你会听到(弃用的坏主意)我的意思是为什么和什么一样重要. (2认同)