我知道javascript函数完全能够调用其他函数。我已多次使用它了。
目前我正在编写一个脚本,它将找到某个标签的html元素,并根据它的标签添加一些文本。
function foo() {
dealWithH1();
dealWithH2();
dealWithH3();
etc...
}
我已经对这样的功能进行了一些搜索,而我似乎无法找到的是对这是否是一种好的做法的明确,一致的答案。我喜欢这种方式,因为有很多函数调用,并且它保持非常有条理。我只是想确保在我做得太过分之前,做这样的事情没有一些明显的问题。函数foo()
没有任何意义,只能在onLoad
调用,然后调用所有其他函数。
这没关系,还是有更鼓励的方式来完成这项工作?
答案 0 :(得分:4)
假设您编写的代码不是完全伪代码,我肯定不会这样做:您将使用许多不同的函数污染全局范围。您可以使用闭包将这些函数包装在本地作用域中,或者使它们成为对象的方法。
此外,dealWithTagH1
,dealWithTagH2
等似乎也有在内部查找这些特定标记并对其进行修改的目的。这是你可以推断的逻辑。因此,您应该拥有能够获得您感兴趣的所有类型标记的内容,然后调用dealWith
函数。通过这种方式,您只有一个代码可以查找代码,而不同的函数可以处理该特定代码。你以这种方式解耦了更多的逻辑。如果你想以一种极端的方式,你可能会有类似战略模式的东西。
我也会修改命名,给每个“策略”一个更好的名称(dealWithTagH1
它非常通用,开发人员认为该代码没有任何关于实现的实际策略的提示)。 / p>
答案 1 :(得分:4)
创建由函数组成的伪DSL操作是完全合理的。
根据您对dealWith...
函数所做的描述,我认为您可能希望更多地概括您的函数,例如:
function foo() {
tagInsert('h1', 'Text to append to h1 tag');
tagInsert('h2', 'Text to append to h2 tag');
tagInsert('h3', 'Text to append to h3 tag');
}
现在该函数的本质已被提炼(将文本追加到指定类型的所有标签),并且函数的变量已经参数化(标签的类型和文本到附加),你可以轻松地做一些事情:
var tags = {
'h1': {
'en': 'Hello',
'es': 'Hola',
'sr@latin': 'Zdravo'
},
'h2': {
'en': 'Goodbye',
'es': 'Adios',
'sr@latin': 'Do vidjenja'
},
'h3': {
'en': 'Green',
'es'; 'Verde',
'sr@latin': 'Zelena'
}
};
function foo(locale) {
for(var tag in tags) {
tagInsert(tag, tags[tag][locale]);
}
}
函数的可组合性得到极大改善,因为你将执行的操作被推迟到实际调用函数之前 - 你可以使用完全相同的函数,现在不只是附加一个固定的标签的文本集,但是以用户喜欢的任何语言进行。
这种灵活性当然可以用于荒谬的长度,你永远不会做任何事情,但最好把你的函数看作一个集合运算符:你的函数的输入是什么(明确声明为变量或隐式声明)通过访问全局)以及执行什么操作来生成新的输出集?
如果以通用方式编写函数而不是您正在处理的特定情况,并不需要花费太多额外的精力,那么就这样编写它,并且只要您需要执行类似的操作就可以重复使用该函数行动,但有不同的投入。
不要将我的tagInsert
定义视为面值,我几乎不知道任何关于你实际上要做的事情,也许这种概括并不真正有意义。重点是你,因为开发人员应该更好地了解你想要完成的任务。
如果你遵循Larry Wall's Virtues of a Programmer,你应该尽量减少你必须做的额外工作量,并且你的功能将达到合适的可组合性与复杂性。
函数调用函数是函数的重点 - 你可以避免一遍又一遍地重写函数;只是将一个大规模的命令行动声明划分为一系列功能是不一个功能点。命令式代码中的重复模式是什么?如何尽可能 lazy ?
答案 2 :(得分:2)
实际上,从维护和可读性的角度来看,几乎任何主流语言的功能/方法都很便宜并且具有尽可能小且内聚的功能。你不应该害怕创建函数,提取它们,在层次结构中调用它们(一个函数调用另一个函数,然后调用第三个函数)。您还应该学习如何使用recursion。
函数(包括匿名函数和闭包)是JavaScript中的主要构建块,它们可以在任何地方使用,例如:事件处理程序和回调。
避免使用比屏幕更长的功能(有人说10行,有些5 - 只是保持简短)。还使用函数来减少重复。例如,有些东西告诉我你的所有dealWithH*()
非常相似。怎么样:
function foo() {
dealWithTag('h1');
dealWithTag('h2');
dealWithTag('h3');
//etc...
}
当然,在你的情况下,单独的函数可能是一个更好的主意,但只需考虑抽象,并试图使问题更加一致。