我怎样才能编写可重用的Javascript?

时间:2010-04-09 15:58:58

标签: javascript code-reuse

我已经开始将我的函数包装在Objects中,例如:

var Search = {
  carSearch: function(color) {
  },
  peopleSearch: function(name) {
  },
  ...
}

这对可读性有很大帮助,但我仍然遇到 reusabilty 的问题。更具体地说,困难在于两个方面:

  1. 接收参数。很多时候我会有一个带有多个输入字段的搜索屏幕和一个调用javascript搜索功能的按钮。我必须在按钮的onclick中放入一堆代码来检索然后将输入字段中的值列入函数调用,或者我必须对HTML输入字段名称/ ID进行硬编码以便随后可以检索它们用Javascript。我为此解决的解决方案是将字段名称/ ID传递给函数,然后使用该函数从输入字段中检索值。这很简单,但似乎不合适。

  2. 返回值。大多数Javascript调用的效果往往是屏幕上的某些视觉直接更改,或者是在调用中执行的另一个操作的结果。当我在功能结束时放置这些屏幕改变效果时,可重用性就是干杯。例如,搜索完成后,我需要在屏幕上显示结果。

  3. 其他人如何处理这些问题?提出我的思考上限让我相信我需要在我的应用程序中的每次使用和我创建的通用方法之间都有一个特定于页面的Javascript层,这些方法将在应用程序范围内使用。使用前面的示例,我将有一个搜索按钮,其onclick调用myPageSpecificSearchFunction,其中搜索字段ID /名称是硬编码的,它会封送参数并调用通用搜索功能。泛型函数只返回数据/对象/变量,不会直接从DOM读取或对DOM进行任何更改。然后,特定于页面的搜索功能将接收该数据并适当地更改DOM。

    我是在正确的道路上还是有更好的模式来处理Javascript对象/方法的重用?

3 个答案:

答案 0 :(得分:24)

基本模式

就基本模式而言,我是否可以建议修改结构以使用模块模式和命名函数:

var Search = (function(){
    var pubs = {};

    pubs.carSearch = carSearch;
    function carSearch(color) {
    }

    pubs.peopleSearch = peopleSearch;
    function peopleSearch(name) {
    }

    return pubs;
})();

是的,这看起来更复杂,但这部分是因为没有涉及辅助功能。请注意,现在,每个函数都有一个名称(您以前的函数是匿名的;它们绑定的属性具有名称,但函数没有,这对调试器中调用堆栈的显示有影响等)。使用模块模式还可以使您具有完全私有的功能,只有Search对象中的功能才能访问。 (只需在大型匿名函数中声明函数,不要将它们添加到pubs。)更多关于我的理由(有优点和缺点,以及为什么不能组合函数声明和属性赋值) here

检索参数

我真正喜欢Prototype的函数之一是Form#serialize函数,它遍历表单元素并根据字段的名称构建一个带有每个字段属性的普通对象。 (Prototype的当前版本 - 1.6.1 - 实现有一个问题,它不保留字段的顺序,但令人惊讶的是,这很少是一个问题。)听起来你会得到很好的服务通过这样的事情,他们并不难建立;那么你的业务逻辑就是处理具有根据它们所关联的属性命名的对象,并且不了解实际的表单本身。

返回值/混合UI和逻辑

我倾向于将应用程序视为对象以及它们之间的连接和交互。所以我倾向于创建:

  • 表示业务模型等的对象,与接口无关(当然,业务模型几乎肯定是由接口部分驱动的)。这些对象在一个地方定义,但同时用于客户端和服务器端(是的,我使用JavaScript服务器端),并设计了序列化(通过JSON,在我的情况下),所以我可以来回发送它们容易。
  • 提示服务器端知道如何使用它们来更新底层存储(因为我倾向于使用底层存储的项目),并且
  • 客户端知道如何使用该信息呈现给UI的对象。

(我知道,几乎没有原创!)我试图保持商店和渲染对象的通用性,所以他们主要通过查看业务对象的公共属性(这几乎是所有属性;我不使用)来工作像Crockford这样的模式可以让你真正隐藏数据,我觉得它们太贵了。实用主义意味着商店或渲染对象有时必须知道他们正在处理什么,特别是,但我确实尽可能保持通用。

答案 1 :(得分:1)

Javascript非常灵活,这意味着您的设计特别重要,因为您可以通过多种不同方式执行操作。这可能使Javascript感觉不太像是为了重新使用。

有一些不同的符号用于声明对象(函数/类),然后命名它们。了解这些差异非常重要。正如在这里的评论中提到的'命名空间是轻而易举的' - 并且是一个很好的起点。

我不能在这个回复中走得太远,只能解释,所以我建议买这些书:

Pro JavaScript Design Patterns

Pro Javascript techniques

答案 2 :(得分:1)

我开始使用module pattern,但随后开始在jQuery plugins中执行所有操作。插件允许传递页面特定选项。

使用jQuery还可以让您重新思考识别搜索字词和查找其值的方式。您可以考虑为每个输入添加一个类,并使用该类来避免专门命名每个输入。