2013-03-25 74 views
7
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>可以在Javascript中定义Object中的原型函数吗?

上面的代码工作正常。

但我记得我看到这个地方:Do not mess with native Object.好,就像那样。

那么可以定义一个原型函数对象?有什么理由不应该这样做吗?

+0

这是一个图书馆其他人将被消耗?或者为你自己的应用程序代码? – 2013-03-25 17:07:16

+0

我在写一个其他人可能也在使用的小型图书馆。正如下面提出的答案,我认为我不应该这样做,不管是谁编写的代码。 – user1643156 2013-03-25 17:17:04

回答

5

比较安全的方法添加到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)浏览器可能会发生抱怨。

+0

虽然现在不是['hasOwnProperty'](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty)是最佳做法吗? – 2013-03-25 17:06:28

+0

@RoatinMarth不,恕我直言'hasOwnProperty'是_old_最佳做法。在ES5浏览器中,应该没有必要。任何与Object.prototype不清的代码应该被放逐。即使jQuery忽略'hasOwnProperty'测试,并明确指出,如果使用滥用它的代码,它会失败。 – Alnitak 2013-03-25 17:07:49

+0

'在以前版本的Javascript中不存在不可枚举的属性。''您用'previous'指代哪个版本? – user1643156 2013-03-25 17:21:14

1

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

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

function MyObject { 
    ... 
} 

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

var myObj = new MyObject(); 
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检查,但是这里的风险在于你可能会打破其他代码,而这些代码并不期望一个普通对象具有文本中指定的其他属性。

+0

自_enumerable_属性已添加... – Alnitak 2013-03-25 17:00:25

+0

@Alnitak更新,谢谢。 – 2013-03-25 17:02:29

0

另一种选择是呼叫的方法,而不是定义为对象的原型方法 -

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

//

doSomething.call(document.getElementById("foo"),"Hello World"); 
相关问题