如何编写可重用的 Javascript?

发布于 2024-08-28 03:14:33 字数 918 浏览 4 评论 0 原文

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

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

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

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

  2. 返回值。大多数 Javascript 调用的效果往往是屏幕上的某些视觉效果直接发生变化,或者作为调用中执行的另一操作的结果。当我将这些屏幕改变效果放在函数末尾时,可重用性就很重要了。例如,搜索完成后,我需要在屏幕上显示结果。

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

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

I've started to wrap my functions inside of Objects, e.g.:

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

This helps a lot with readability, but I continue to have issues with reusabilty. To be more specific, the difficulty is in two areas:

  1. Receiving parameters. A lot of times I will have a search screen with multiple input fields and a button that calls the javascript search function. I have to either put a bunch of code in the onclick of the button to retrieve and then martial the values from the input fields into the function call, or I have to hardcode the HTML input field names/IDs so that I can subsequently retrieve them with Javascript. The solution I've settled on for this is to pass the field names/IDs into the function, which it then uses to retrieve the values from the input fields. This is simple but really seems improper.

  2. Returning values. The effect of most Javascript calls tends to be one in which some visual on the screen changes directly, or as a result of another action performed in the call. Reusability is toast when I put these screen-altering effects at the end of a function. For example, after a search is completed I need to display the results on the screen.

How do others handle these issues? Putting my thinking cap on leads me to believe that I need to have an page-specific layer of Javascript between each use in my application and the generic methods I create which are to be used application-wide. Using the previous example, I would have a search button whose onclick calls a myPageSpecificSearchFunction, in which the search field IDs/names are hardcoded, which marshals the parameters and calls the generic search function. The generic function would return data/objects/variables only, and would not directly read from or make any changes to the DOM. The page-specific search function would then receive this data back and alter the DOM appropriately.

Am I on the right path or is there a better pattern to handle the reuse of Javascript objects/methods?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

盛装女皇 2024-09-04 03:14:33

基本模式

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

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

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

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

    return pubs;
})();

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

检索参数

我非常非常喜欢 Prototype 的功能之一是 Form#serialize 函数,它遍历表单元素并为每个元素构建一个带有属性的普通对象基于字段名称的字段。 (Prototype 当前的 – 1.6.1 – 实现存在一个问题,即它不保留字段的顺序,但令人惊讶的是,这种问题很少出现。)听起来您会没事的-由这样的东西提供服务,而且它们并不难建造;那么您的业务逻辑正在处理具有根据其相关内容命名的属性的对象,并且不了解实际表单本身。

返回值/混合 UI 和逻辑

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

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

(我知道,这几乎不是原创!)我尝试保持存储和渲染对象的通用性,因此它们主要通过查看业务对象的公共属性来工作(这几乎是所有属性;我不使用像Crockford 可以让你真正隐藏数据,我发现它们太贵了)。实用主义意味着有时存储或渲染对象只需要知道它们正在处理的具体内容,但我确实尽力使事情保持通用。

Basic Pattern

In terms of your basic pattern, can I suggest modifying your structure to use the module pattern and named functions:

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

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

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

    return pubs;
})();

Yes, that looks more complicated, but that's partially because there's no helper function involved. Note that now, every function has a name (your previous functions were anonymous; the properties they were bound to had names, but the functions didn't, which has implications in terms of the display of the call stack in debuggers and such). Using the module pattern also gives you the ability to have completely private functions that only the functions within your Search object can access. (Just declare the functions within the big anonymous function and don't add them to pubs.) More on my rationale for that (with advantages and disadvantages, and why you can't combine the function declaration and property assignment) here.

Retrieving Parameters

One of the functions I really, really like from Prototype is the Form#serialize function, which walks through the form elements and builds a plain object with a property for each field based on the field's name. (Prototype's current – 1.6.1 – implementation has an issue where it doesn't preserve the order of the fields, but it's surprising how rarely that's a problem.) It sounds like you would be well-served by such a thing and they're not hard to build; then your business logic is dealing with objects with properties named according to what they're related to, and has no knowledge of the actual form itself.

Returning Values / Mixing UI and Logic

I tend to think of applications as objects and the connections and interactions between them. So I tend to create:

  • Objects representing the business model and such, irrespective of interface (although, of course, the business model is almost certainly partially driven by the interface). Those objects are defined in one place, but used both client- and server-side (yes, I use JavaScript server-side), and designed with serialization (via JSON, in my case) in mind so I can send them back and forth easily.
  • Objects server-side that know how to use those to update the underlying store (since I tend to work on projects with an underlying store), and
  • Objects client-side that know how to use that information to render to the UI.

(I know, hardly original!) I try to keep the store and rendering objects generic so they mostly work by looking at the public properties of the business objects (which is pretty much all of the properties; I don't use the patterns like Crockford's that let you really hide data, I find them too expensive). Pragmatism means sometimes the store or rendering objects just have to know what they're dealing with, specifically, but I do try to keep things generic where I can.

雪化雨蝶 2024-09-04 03:14:33

我开始使用 模块模式,但随后开始在 jQuery 插件< /a>.该插件允许传递页面特定选项。

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

I started out using the module pattern, but then started doing everything in jQuery plugins. The plugins allow to pass page specific options.

Using jQuery would also let you rethink the way you identify your search terms and find their values. You might consider adding a class to every input, and use that class to avoid specifically naming each input.

无尽的现实 2024-09-04 03:14:33

Javascript 非常灵活,这意味着您的设计尤其重要,因为您可以通过多种不同的方式完成任务。这可能会让 Javascript 感觉不太适合重用。

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

我在这个回复中无法走得足够远,只能进行释义,所以我建议购买这些书:

专业 JavaScript 设计模式

专业 Javascript 技术

Javascript is ridiculously flexible which means that your design is especially important as you can do things in many different ways. This is what probably makes Javascript feel less like lending itself to re-usability.

There are a few different notations for declaring your objects (functions/classes) and then namespacing them. It's important to understand these differences. As mentioned in a comment on here 'namespacing is a breeze' - and is a good place to start.

I wouldn't be able to go far enough in this reply and would only be paraphrasing, so I recommend buying these books:

Pro JavaScript Design Patterns

Pro Javascript techniques

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文