2012-03-01 90 views
1

这就是我想要实现的。下面是代码的现有片 -在JavaScript中动态定义函数名称?

function PartMetaData(dataElement) { 
this.metaData = new MetaData(dataElement); 

this.getDescription = function() { 
    return this.metaData.getElement("data-part-description"); 
}; 

this.getLength = function() { 
    return this.metaData.getElement("data-part-length"); 
}; 

this.getWidth = function() { 
    return this.metaData.getElement("data-part-width"); 
}; 

this.getHeight = function() { 
    return this.metaData.getElement("data-part-height"); 
}; 

this.getWeight = function() { 
    return this.metaData.getElement("data-part-weight"); 
}; 
} 

现在看functionname和属性名之间的关系 - 这看起来很像可以避免重复的代码。那是可以实现的吗?有没有办法让一个对象的“任何”函数调用,并根据函数名称确定要做什么?

用于例如像(语法熟了,我不知道这样的事情在Javascript中存在,或任何其他语言为此事)

function PartMetaData(dataElement){ 
this.metaData = new MetaData(dataElement); 

this.get(name?) = function() { 
    return this.metaData.getElement("data-part-" + name.toLower()); 
} 

使得来电者仍可以调用

partMetaData.getDescription(); 

任何想法?我知道我可以更改签名并使其成为一个功能,我只想知道签名是否可以保留为一些JS(黑色?)魔术。谢谢!

回答

3

您可以创建一个辅助函数,您可以像这样使用它来创建所有这些方法。

function PartMetaData(dataElement) { 
    this.metaData = new MetaData(dataElement); 

    function makeAccessor(o, itemName) { 
     var ucase = itemName.substr(0,1).toUpperCase() + itemName.substr(1); 
     o["get" + ucase] = function() { 
      return this.metaData.getElement("data-part-" + itemName); 
     } 
    } 

    var items = ["description", "weight", "height", "width", "length"]; 
    for (var i = 0; i < items.length; i++) { 
     makeAccessor(this, items[i]); 
    } 
} 

一个稍微不同的接口这样做的一个简单的方法是这样的:

function PartMetaData(dataElement) { 
    this.metaData = new MetaData(dataElement); 
    this.getProperty = function(name) { 
     return this.metaData.getElement("data-part-" + name); 
    } 
} 

而且,你会使用这样的:

partMetaData.getProperty("height"); 
+0

+1 I就像第一个选项一样,我试图避免第二个选项。然而,即使在这里,我也需要事先知道可能进入哪种类型的呼叫。有没有办法不这样做? (约束可能是避免异常的好办法,但我仍然想知道是否有办法避免这种情况)。 – 2012-03-01 06:07:23

+0

@RoopeshShenoy - 您可以通过使'makeAccessor()'函数成为公共方法并在使用访问器方法之前让别人调用它来动态添加方法。但是,如果没有先定义方法,你不能只拥有一个方法。有人必须在可以使用之前对其进行定义。 getProperty()解决方案提供了100%动态选项,无需事先定义任何内容。 – jfriend00 2012-03-01 06:15:52

+0

看起来像这样,实际上我比第一个更喜欢第二个选项,但如果可以的话,我不想更改界面。遗留代码:-(需要大量的重构 – 2012-03-01 06:18:40

0

呀,combinging jfriend的解决方案很好地工作:

function PartMetaData(dataElement) { 
    this.metaData = new MetaData(dataElement); 

    this.getProperty = function(name) { 
     return this.metaData.getElement("data-part-" + name); 
    } 

    this.makeAccessor = function(name) { 
     this["get" + name.substr(0,1).toUpperCase() + name.substr(1)] = 
      function() { return this.getProperty(name); } 
    } 

    var items = ["description", "weight", "height", "width", "length"]; 
    for (var i = 0; i < items.length; i++) { 
     this.makeAccessor(this, items[i]); 
    } 
}