可以在Javascript中定义Object上的原型函数吗?

时间:2013-03-25 16:56:09

标签: javascript function object prototype

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.好吧,就像那样。

那么在对象上定义原型函数是否可以?我有什么理由不这样做吗?

4 个答案:

答案 0 :(得分: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)浏览器可能会抱怨如果您这样做

答案 1 :(得分:1)

一般不是个好主意。该功能现在可以在您的应用程序中使用Object原型(很多)的所有中获得,并将显示在枚举Object proto的函数中。

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

function MyObject {
    ...
}

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

var myObj = new MyObject();

答案 2 :(得分: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检查,但此处的风险是您可以破坏其他代码,这些代码不希望普通对象具有除了在文字。

答案 3 :(得分:0)

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

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

//

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