8
Object.prototype.doSomething = function(p) {
    this.innerHTML = "<em>bar</em>";
    this.style.color = "#f00";
    alert(p);
};

document.getElementById("foo").doSomething("Hello World");

<div id="foo"><strong>foo</strong></div>

上面的代码工作正常。

但我记得我在某个地方看到过这个:Do not mess with native Object.嗯,类似的。

那么在Object上定义原型函数可以吗?有什么理由我不应该这样做吗?

4

4 回答 4

7

唯一安全的添加方法Object.prototype是使用 ES5 方法Object.defineProperty创建一个不可枚举的属性:

Object.defineProperty(Object.prototype, 'doSomething', {
    value: function(p) { ... },
    enumerable: false,  // actually the default
});

这样可以确保在您这样做时不会出现新属性for (key in object)

请注意,此函数不能可靠地填充,因为不可枚举的属性在以前版本的 ECMAScript / JavaScript 中不存在。

无论如何,如果您的方法仅适用于 HTML 页面元素,则最好将其添加到Element.prototype而不是添加到Object.prototype,尽管如果您这样做,旧的 (IE) 浏览器可能会抱怨。

于 2013-03-25T16:59:00.267 回答
1

通常不是一个好主意。该函数现在可用于您的应用程序中使用 Object 原型(很多)的所有内容,并将显示在枚举 Object 原型的函数中。

更好的选择是定义一个单独的原型:

function MyObject {
    ...
}

MyObject.prototype.doSomething = function() {
    ...
}

var myObj = new MyObject();
于 2013-03-25T16:59:21.963 回答
1

如果您向对象原型添加内容,您将失去使用 的良好对象迭代功能for p in obj,因为您添加的可枚举属性也会在所有对象上进行迭代。

例如:

Object.prototype.doSomething = function(p) {
    this.innerHTML = "<em>bar</em>";
    this.style.color = "#f00";
    alert(p);
};

for (p in {foo:"bar"}){
    console.log(p);
}

//foo
//doSomething

出乎意料的是,您也会被doSomething登录。要解决此问题,您必须hasOwnproperty在迭代对象时添加检查,但这里的风险是您可能会破坏其他不期望普通对象具有除文字中指定的属性之外的属性的代码。

于 2013-03-25T16:59:51.677 回答
0

另一种选择是调用一个方法,而不是定义为对象原型方法-

function doSomething(p) {
    this.innerHTML = "<em>"+p+"</em>";
    this.style.color = "#f00";
    alert(p);
};

//

doSomething.call(document.getElementById("foo"),"Hello World");
于 2013-03-25T17:09:35.837 回答