When I first started with Javascript, I usually just put whatever I needed into functions and called them when I needed them. That was then.
Now, as I am building more and more complex web applications with Javascript; taking advantage of its more responsive user interaction, I am realizing that I need to make my code more readable - not only by me, but anyone who replaces me. Besides that, I would like the reduce the moments of 'what the heck, why did I do this' when I read my own code months later (yes, I am being honest here, I do have what the heck was I thinking moments myself, although I try to avoid such cases)
A couple weeks ago, I got into Joose, and so far, it has been good, but I am wondering what the rest do to make their chunk their codes into meaningful segments and readable by the next programmer.
Besides making it readable, what are your steps in making your HTML separated from your code logic? Say you need to create dynamic table rows with data. Do you include that in your Javascript code, appending the td element to the string or do you do anything else. I am looking for real world solutions and ideas, not some theoretical ideas posed by some expert.
So, in case you didnt't understand the above, do you use OOP practices. If you don't what do you use?
-
My answer to similar question: stackoverflow.com/a/56115623/2534191Yuriy N.– Yuriy N.2019年05月13日 16:25:12 +00:00Commented May 13, 2019 at 16:25
7 Answers 7
For really JS-heavy applications, you should try to mimic Java.
- Have as little JS in your HTML as possible (preferably - just the call to the bootstrap function)
- Break the code into logical units, keep them all in separate files
- Use a script to concatenate/minify the files into a single bundle which you will serve as part of your app
- Use JS namespaces to avoid cluttering up the global namespace:
var myapp = {};
myapp.FirstClass = function() { ... };
myapp.FirstClass.prototype.method = function() { ... };
myapp.SecondClass = function() { ... };
Using all these techniques together will yield a very manageable project, even if you are not using any frameworks.
3 Comments
I use unobtrusive javascript, so, outside of the script tags I don't keep any javascript in the html.
The two are completely separated.
A javascript function will start when the DOM tree is completed, which will go through the html and add the javascript events, and whatever else needs to be changed.
In order to organize, I tend to have some javascript files that are named similar to the html pages that they use, and then for common functions I tend to group them by what they do, and pick a name that explains that.
So, for example, if I have UI functions then I may call them: myapp_ui_functions.js
I try to put the name of the application in the filename, unless there is some javascript that is common to several projects, such as strings.js.
2 Comments
I have (usually) one file that contains a bunch of functions and that's it. That is included in every page that uses Javascript. In the pages themselves, I'll make the calls to the functions like:
$(function() {
$("#delete").click(delete_user);
$("#new").click(new_user);
});
where delete_user() and new_user() are defined in the external file.
I too use unobtrusive Javascript, which for me means jQuery (there are other libraries that are unobtrusive).
You don't want a separate file for each page. That just means more unnecessary external HTTP requests. With one file—assuming you've cached it effectively—it'll be downloaded once and that's it (until it changes).
If I have a large amount of Javascript or the site is effectively split into multiple areas then I may split the Javascript but that's not often the case.
Also, in terms of my source code, I may have multiple JS files but I'll often end up combining them into one download for the client (to reduce HTTP requests).
More at Multiple javascript/css files: best practices? and Supercharging Javascript in PHP.
3 Comments
I prefer to organize JavaScript code using objects (classes) based on functionality.
Theory
- Classes are named after functionality they implement, e.g.
ContextMenu,UserList,Dialogetc. - Each class goes into its own file named after the name of the class. E.g.
context_menu.js,user_list.jsetc, notconstants.js,authentication.jsand so on. The files have no other code besides the class definition. - Class constructor is used to attach events using Unobtrusive JavaScript approach and create any HTML a particular feature requires.
<template>tag is used if dynamic HTML is needed. - There is a single file called
app.js, which serves as a kind of entry point which creates objects from classes found in above mentioned files. Obviously, they need to be loaded first.
Practice
Say, we are implementing a class to represent a context menu. We create the new class ContextMenu and declare that it can be used as a module:
context_menu.js:
export class ContextMenu {
constructor() {
this.#createHtml();
document.addEventListener('click', this.#close.bind(this));
target.addEventListener('contextmenu', (e) => {
e.stopPropagation();
});
}
#open() {}
#createHtml() {
const container = document.createElement('ul');
container.classList.add(this.#containerCssClassName);
container.hidden = true;
this.#container = container;
document.body.appendChild(container);
}
}
Then in some another module we are importing the menu and start using it:
app.js:
import { ContextMenu } from "./context_menu.js";
const menu = new ContextMenu();
- Irrelevant method implementations were omitted for brevity.
- A real world example and the full code listing can be found at the ContextMenu project repository.
Comments
I've been rewriting a lot of my reusable code as jQuery plugins. I moved to jQuery from Prototype when I started doing ASP.NET MVC. Overtime I've migrated a lot my reusable code, or at least the ideas, from Prototype-based OO to jQuery-style plugins. Most of these are stored in their own JS files (mainly intranet apps so page load speed is pretty high anyway despite the extra requests). I suppose I could add a build step that coalesces these if I needed to.
I've also settled on a MasterPage approach that uses a ContentPlaceHolder for scripts that is right before the closing body tag. The standard jQuery/jQuery UI loads, and any other common JS goes right before the script placeholder in the MasterPage. I have tiny bit of JS at the top of the MasterPage that defines an array that holds any functions that partial views need to run on page load. These functions are run from the base document.ready() function in the MasterPage.
All of my JS is completely separate from my mark up. Some JS may exist in partial views -- these are encapsulated when the partial may be included more than once to make it specific to that instance of the view -- but generally not. Typically only included in the placeholders so that it's loaded at the bottom of the page.
2 Comments
Also, if you want to go OO heavy, check out mochikit: http://www.mochikit.com/
1 Comment
I find that developing your javascript using OO methodology is the way to go if you want it to be clean, readable and even somewhat secure. I posted the following question
Cleanest format for writing javascript objects
And got some fantastic responses on how to write my javascript code well. If you follow these basic principles you can use almost any library, such as yui, jquery and prototype, with ease.