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:
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.
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?
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.
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.
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
Related
This question is regarding a best practice for structuring data objects using JS Modules on the server for consumption by another module.
We have many modules for a web application, like login view, form handlers, that contain disparate fragments of data, like user state, application state, etc. which we need to be send to an analytics suite that requires a specific object format. Where should we map the data? (Pick things we want to send, rename keys, delete unwanted values.)
In each module. E.g.: Login knows about analytics and its formatting
requirements.
In an analytics module. Now analytics has to know
about each and every module's source format.
In separate [module]-analytics modules. Then we'll have dozen of files which don't have much context to debug and understand.
My team is split on what is the right design. I'm curious if there is some authoritative voice on the subject that can help us settle this.
Thanks in advance!
For example,
var objectForAnalytics = {
logged_in: user.get('isLoggedIn'),
app_context: application.get('environment')
};
analytics.send(objectForAnalytics);
This short sample script uses functions from 3 modules. Where should it exist in a well-organized app?
JS doesn't do marshaling, in the traditional sense.
Since the language encourages duck typing and runs all loaded modules in a single VM, each module can simply pass the data and let a consumer choose the fields that interest them.
Marshaling has two primary purposes, historically:
Delivering another module the data that it expects, since C-style structures and objects do not support extra data (usually).
Transferring data between two languages or modules built on two compilers, which may be using different memory layouts, calling conventions, or ABIs.
JavaScript solves the second problem using JSON, but the first is inherently solved with dictionary-style objects. Passing an object with 1000 keys is just as fast as an object with 2, so you can (and often are encouraged) to simply give the consumer what you have and allow them to decide what they need.
This is further reinforced in languages like Typescript, where the contract on a parameter type is simply a minimum set of requires. TS allows you to pass an object that exceeds those requires (by having other fields), instead only verifying that you are aware of what the consumer states they require in their contract and have met that.
When you do need to transform an object, perhaps because two library use the same data with different keys, creating a new object with shallow references is pretty easy:
let foo = {
bar: old.baz,
baz: old.bin
};
This does not change or copy the underlying data, so any changes to the original (or the copy) will propagate to the other. This does not include primitive values, which are immutable and so will not propagate.
For example:
module.exports = {
myLibraryFunction: function myLibraryFunction() {
...
}
}
The disadvantage is obvious. It's not very DRY, which means it can easily become out-of-sync if you're not careful. It also makes your code a little more verbose.
So what are the advantages? Is the tradeoff worth it?
I use this approach when writing JS libraries. The largest advantage is that tools like the Chrome debugger will have a definite name for your function as opposed to either "anonymous" or some name composed of the function path based on the variable names containing the function. If, however, you don't care about having method names when debugging, then it really comes down to a matter of taste. If you were to minify the resulting JS code, naming elements like that would get stripped out anyway.
As far as to how DRY this approach is, consider that the repeated names occur right next to each other. A quick copy & paste is all it takes to keep them in sync. It would be nice if a JS included a feature that causes a function to be named according to the variable it has been assigned to at the point of creation (or at least the ability to dynamically re-assign the function's name). Sadly, however, this is the only way JS allows for us to name these otherwise anonymous functions.
I am wondering how to structure a KnockoutJS application the right way.
The official documentation almost always uses just one single ViewModel!
After only a few implemented functions my code became very confusing and coming from an object-oriented background I am very allergic to architecture like that. So there must be a better solution.
Being not very experienced with JavaScript I was searching Stackoverflow and found those three options. So I tried the first two options and I am not happy with them:
Having multiple ViewModels like here.
I find it very difficult to decide what DOM-element gets what ViewModel. Also there were several functions called from outside the DOM-element. Maybe I used too little ViewModels with this kind of architecture but communicating between ViewModels seemed to be different and somehow shouldn't be necessary I hope. So how to do that properly?
Having sub views and utilizing the with binding (the second option from those three).
This was my preferred type of architecture because you can have document-wide bindings out of one view model but you can also structure your code into sub-chunks and bind them to wherever you want by using the with binding. This option though requires object literals instead of functions, which are inferior as described in this answer.
I haven't tried method three because it seems a little overkill and also uses object literals.
So is there a method to structure my code and also have full control without using object literals?
I hope this was not too confusing :-P
For any of the options that you mentioned, you do not need to use object literals. The samples just used them to simplify the code. You can choose to create the individual view models in any way that you see fit.
For example in #3, you can use a constructor function like: http://jsfiddle.net/rniemeyer/PctJz/149/. Of course, the actual data would get passed into the function rather than being static. Same with #2, you just would have it wrapped in the "View" object.
Someone mentioned that immediate or self-executing functions have to store the whole stack. Is this true...If so what are the pros and cons of using something like the module pattern (which is based on an immediate function) vs. a plain function?
A function is inherently private, but you can return items that you want to be public, so it can handle privacy.
The main difference I see, is that you don't have global imports or the ability to make sure that the developer ( wait that's me ) uses new with the function ( or it is complicated ).
In general when trying to provide privacy and state when should one use the module pattern and when should one just use a plain function?
A second side question is does a function provide state when used with new?
Any function closure that persists because there are lasting references to variables or functions inside it occupies some amount of memory. In today's computers (even phones), this amount of memory is generally insignificant unless you're somehow repeating it thousands of times. So, using the language features to solve your design problems is generally more important than worrying about this amount of memory.
When you say "the whole stack", the calling stack for a top-level self-executing function is very small. There's really nothing else on the stack except for the one function that's being called.
A function is also an object. So, when it's used with new, it creates a new object that can have state (it's properties) if you assign values to those properties. That's one of the main ways that objects are created in javascript. You can either call a function and examine it's return value or you can use it with new and the function serves as the constructor for a new object. A given function is usually designed to be used in one way or the other, not both.
The module pattern is generally used to control which variables are public and when making them public to put them into a structured namespace that uses very few top-level global variables. It isn't really something you choose instead of self-executing functions because they don't really solve the same problem. You can read more about the module pattern here: http://www.yuiblog.com/blog/2007/06/12/module-pattern/
You can read about a number of the options here: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth and http://www.klauskomenda.com/code/javascript-programming-patterns/.
It is easier to discuss the pros/cons of a given technique in light of a specific problem that one is trying to solve or a specific design issue rather than a generic discussion of which is better when the things you've asked about are not really solving equivalent issues.
The best reference I know of for protected and private members (which can be hacked into javascript, but are not a core language feature) is this one: http://javascript.crockford.com/private.html. You are making tradeoffs when you use this method instead of the default prototype feature of the language, but you can achieve privacy if you really need it. But, you should know that javascript was not build with private or protected methods in mind so to get that level of privacy, you're using some conventions about how you write your code to get that.
I seem to often be making the decision to create objects in javascript that are basically the ModelView or Model objects in an MVC architecture. So when the user changes their properties or whatever via the webpage, the javascript object's properties are changed, and then the javascript object is submitted to the controller. The main reasons I am using this approach are:
Increased flexibility of display.
Alternatively, everything is done
with forms so that I can easily post
them back to the controller. Forms do
not allow various display options
such as wrapping around other
elements and so on.
I am using a lot of javascript
anyway. I have to manipulate the
elements whenever buttons are pressed
(like swapping two list elements
around). I also usually hijack the
buttons and use them with ajax.
The default model binder rarely works
on complex objects so I need to
maintain two sets of objects anyway.
It is easier to perform complex
validation on a javascript object
compared to html.
Are there any libraries or techniques or approach that assist with this approach? Maybe JSON.NET? Do any people try to avoid this approach?
I haven't taken this approach myself but there are some frameworks that sound similar to what you are proposing. The one that looks most interesting is Knockout JS. It provides data binding to your model among other features.