向现有Javascript对象添加方法的最佳方法

时间:2013-03-12 16:52:37

标签: javascript prototype

我收到的文件看起来像这样的ajax feed(简化得很多):

aDocs = [{title:'new doc', ext:'pdf'}, {title:'another', ext:'xlsx'}];

我将遍历aDocs数组并显示有关每个文档的信息,同时为每个文档添加一些方法,允许修改HTML以进行显示并进行API调用以更新数据库。

我读了here,为了向现有对象添加方法,您可以使用__proto__属性。有点像:

function Doc(){}
Doc.prototype.getExt = function(){return this.ext}
Doc.prototype.getTitle = function(){return this.title}
for (var i=0; i<aDocs.length; i++){
  aDocs[i].__proto__ = Doc.prototype
}

根据上面的那篇文章,这不是官方的javascript,IE不支持(永远不会),并且可能会在webkit浏览器中弃用。

这是另一种选择:

function getExt(){ return this.ext }
function getTitle(){return this.title}
for (var i=0; i<aDocs.length; i++){
  aDocs[i].getExt = getExt;
  aDocs[i].getTitle = getTitle;
}

这第二种选择是否可行且有效?或者我是在重新创建这些功能,从而产生多余的开销?

以上示例再次简化(我知道aDocs[i].ext将解决上述问题,但我的显示和API调用方法更复杂)。

3 个答案:

答案 0 :(得分:7)

  

这第二种选择是否可行且有效?

  

或者我是否正在重新创建这些功能,从而产生多余的开销?

不,这些功能可以重复使用,而不是重新创建。所有对象都将共享getExtgetTitle函数的副本。在(例如)aDocs[1]调用函数期间,在调用中,this将引用函数附加到的对象。 (这仅适用于将其称为从对象中检索它的表达式的一部分,例如var title = aDocs[1].getTitle();

或者,如果您喜欢,可以创建共享原型的新对象,并将aDocs对象的属性复制到新对象,但是您已经询问了如何为现有分配新功能对象,所以......

答案 1 :(得分:2)

扩充(添加方法)原型通常是最好的方法,但是由于你正在处理对象文字(或JSON.parse结果),你必须 扩充<{1>} 未完成,或创建包装器构造函数,并使用您需要附加到其原型的方法。问题是:在这种情况下掌握Object.prototype ...我会保留原样:使用第二种方法:一个简单的循环就可以了。此外:无论如何原型方法(略微)慢......

正在尽快创建函数对象本身(如果它们在全局命名空间中定义,则在解析脚本时立即创建它们)。通过简单地循环遍历这些对象,并为每个对象分配对任何函数的引用,您根本不会创建其他函数。
试试这个:

this

已经发布了许多问题(和答案)更深入地处理这个问题,所以如果你有兴趣:

Objects and functions in javascript
Print subclass name instead of 'Class' when using John Resig's JavaScript Class inheritance implementation
What makes my.class.js so fast?
What are the differences between these three patterns of "class" definitions in JavaScript?

是否与您的问题或多或少相关

答案 2 :(得分:1)

在这种情况下,我只是将对象传递给Doc;

的构造函数
function Doc(obj){
   this.obj = obj;
}

Doc.prototype.getExt = function(){
    return this.obj.ext;
}
Doc.prototype.getTitle = function(){
   return this.obj.title;
}

var docs = [];
for (var i=0; i<aDocs.length; i++){
  docs.push(new Doc(aDocs[i]));
}

您的方法存在两个问题:

  • 您必须为每个实例单独复制每个方法。
  • 你的“class”没有记录在任何地方,使它成为一个类,使你的对象更清楚你的对象有这些方法。