我已经使用Google图表+ jQuery API编写了一些不错的包装器,可以在鼠标悬停时进行更新。我正在重构我的代码。我有返回具有属性的对象的函数,这些属性本身具有其他属性,依此类推。有很多函数返回带有属性的对象数组,其中一些是数组等。
以下是我的代码示例,该代码从ajax XML树加载ROC和似然表的集合:
function XMLAttributeTable(subtree, point_name, arr_of_attributes) {
// note: assumes numeric attribute values
var attributes_for_each_point = [];
$(subtree).find(point_name).each(function() {
row = $(this);
var point = {};
arr_of_attributes.forEach( function(attr_name) {
point[attr_name] = parseFloatPlus(row.attr(attr_name));
});
attributes_for_each_point.push(point);
});
return attributes_for_each_point;
}
function XMLAttributeTableCollection(subtree, instance_name, point_name, arr_of_attributes) {
// note: assumes the series are in order
var tables_for_each_instance = [];
$(subtree).find(instance_name).each( function() {
tables_for_each_instance.push( XMLAttributeTable( this, "point", arr_of_attributes ) );
});
return tables_for_each_instance;
}
function getROCSeriesForEachRanking(roc_subtree) {
return XMLAttributeTableCollection(roc_subtree, 'roc_series', 'point', ['index', 'target_groups', 'q_value']);
}
function getLikelihoodSeriesForEachRanking(likelihood_subtree) {
return XMLAttributeTableCollection(likelihood_subtree, 'likelihood_series', 'point', ['index', 'likelihood']);
}
这些功能有很多,而且我并不是这个功能的粉丝(分离问题感觉非常困难)。我可能会尝试使用其他语言(即C ++)的语义来编写JavaScript,如果是这样的话,感谢您的建议。但我无法摆脱有代码味的感觉。
所以我的问题是,JavaScript中的构造函数有什么用?如果强类型或强制封装没有实用选项,那么为什么要使用构造函数呢?在这种情况下,我似乎无法弄清楚如何使用成员函数来改善我的生活,因此“继承”似乎并不是非常有用。
非常感谢您提供的任何建议。
答案 0 :(得分:0)
虽然JavaScript是动态和弱类型的,但似乎运算符new
的使用是Brendan Eich抛出的设备,当他真正想要一个Scheme时,使语言看起来更像C和Java类似于开头的语言(有关此apochryphal故事的更多信息,请参阅this post by Brendan Eich),您可能从构造函数中获得一些优势:
很多人从JavaScript开始就使用构造函数,并且很容易理解你的代码。
在创建对象的表达式中使用 new 运算符看起来就像是在创建一个新对象。如果您的函数被称为XmlAttributeTable
,并且您在不使用new
的情况下将其称为函数,那么您创建任何内容都不太清楚。也就是说,如果您调用方法newTable
或createTable
或makeTable
,那也可以。
如果您使用Object.create
,构造函数会带来一点魔力,您需要额外的代码行才能实现。这包括简化构造并使原型具有随时可用的构造函数属性。
考虑:
function Point(x, y) {
this.x = x
this.y = y
}
与
function makePoint(x, y) {
var point = Object.create(theProtoPointIDeclaredEarlier);
point.x = x;
point.y = y;
return this;
}
我已多次阅读Object.create
应优先使用new
,但实际上我并未将运算符new
视为如此邪恶。我知道很多人可能在这里不同意,这很好。 Eich声称在为期10天的JavaScript设计中犯了一些“错误”(参见他在JSConf 2010上的主题演讲),但我从未听过他对构造函数的遗憾。
因此,恕我直言,构造函数式的编码可以帮助您提高可读性,特别是如果您创建的大量对象都属于同一类型。但是,这种风格可能不适合你。
如果您有许多一次性对象,它们看起来都不属于同一个“类型”,那么请避免使用构造函数并将对象作为命名属性的容器处理。这完全没问题。
请记住,JavaScript不是基于类的OOP语言,因此如果需要派生属性,请使用原型。在JavaScript这样的语言中,继承并不是你会非常关心的事情(Crockford在几个不同的地方都很好地说明了这一点)。但是,因为继承对你没有帮助,所以不需要构造函数是错误的。可以在不进行任何继承的情况下使用构造函数。
因此,无论你是否想要使用构造函数,IMHO都归结为你是否有很多看起来相同的对象,而不是你是否有一次性对象。但是你可以很容易地没有它们。特别是在前一种情况下,原型对象可以很好地保持常见的行为。但您也可以将常见行为放在Object.create
的原型中。
当你问“代码味道”时,我可能会在没有getter方法的情况下做。现代JavaScript允许您使用get
属性创建属性,当您想要读取属性并执行代码时,该属性是干净的。更好的恕我直言,而不是命名一个陈述get
的方法。此外,如果你的吸气剂不只是访问一个属性,你可以找到一个更好的名字。