每个JS意见领袖都说扩展原生对象是一种不好的做法.但为什么?我们是否获得了性能?他们是否害怕有人以"错误的方式"做到这一点,并添加了可枚举的类型Object,几乎破坏了任何对象上的所有循环?
以TJ Holowaychuk的should.js为例.他增加了一个简单的getter来Object,一切工作正常(来源).
Object.defineProperty(Object.prototype, 'should', {
set: function(){},
get: function(){
return new Assertion(Object(this).valueOf());
},
configurable: true
});
Run Code Online (Sandbox Code Playgroud)
这真的很有道理.例如,可以扩展Array.
Array.defineProperty(Array.prototype, "remove", {
set: function(){},
get: function(){
return removeArrayElement.bind(this);
}
});
var arr = [0, 1, 2, 3, 4];
arr.remove(3);
Run Code Online (Sandbox Code Playgroud)
是否有任何反对扩展本机类型的论据?
我正在尝试定义一个"点函数",其中没有参数,但.在它之前有一个和一个字符串或数字:
.toUpperCase().
toLowerCase().
indexOf
().
charAt().substring()
你这样做2..toString,不是toString(2).
你如何定义其中之一?
为什么当我输入4..toString()它返回function toString() {[native code]}?
通常人们会编写如下代码:
function Shape() {
this.x = 0;
this.y = 0;
}
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
}
Run Code Online (Sandbox Code Playgroud)
但是,我试图想出一种方法来定义原型上的函数,而不将函数定义与构造函数分开.这是我得到的:
Object.prototype.method = function(name, func) {
if (typeof(this.constructor.prototype[name]) === 'undefined') {
this.constructor.prototype[name] = func
}
}
Run Code Online (Sandbox Code Playgroud)
这允许您执行以下操作:
function Shape() {
this.x = 0;
this.y = 0;
this.method('move', function(x, y) {
this.x += x;
this.y += y;
})
}
Run Code Online (Sandbox Code Playgroud)
而且无论您创建多少次形状,该功能都只会被定义一次.
我知道扩充Object.prototype不被认为是一种好习惯.但除此之外,这种方法有任何缺点吗?
编辑:
约翰提出了一个好点; 我应该做的method不是可枚举的.这是修订版:
Object.defineProperty(Object.prototype, 'method', {
value: function(name, func) {
if (typeof(this.constructor.prototype[name]) === …Run Code Online (Sandbox Code Playgroud)