Home Designing and Linking JavaScript Files
Unobtrusive JavaScript
Always use unobtrusive JavaScript to keep all JavaScript commands entirely out of
your HTML
and entirely inside your JavaScript file. The only
JavaScript-related change to your HTML
file is to link to your
.js
file using a script
tag. No onclick
,
onchange
, onmouseover
, etc. handlers should ever be
declared in your HTML
files.
Here is an example of (bad) obtrusive JavaScript (with the HTML
and
associated JavaScript function):
<!-- bad (HTML) --> <button onclick="foo();">Click me!</button>
// bad (JS) function foo() { alert("You clicked the button!"); }
Here is an example of (good) unobtrusive JavaScript (with the
HTML
and associated JavaScript code):
<!-- good (HTML) --> <button id="clickme"gt;Click me!</button>
// good (JS) window.addEventListener("load", function); function initialize() { document.getElementById("clickme").addEventListener("click", foo); } function foo() { alert("You clicked the button!"); }
use strict
Always write a "use strict";
declaration at the top of your
JavaScript file to tell the browser to enable strict syntax checking of
your JavaScript code.
The Module Pattern
Wrap Your JS File's Code Into an Anonymous Function
Always use the "module pattern" of wrapping your JavaScript file's code inside an
anonymous function that is immediately invoked to get rid of global variables. This
is important because if multiple JavaScript files are linked to the same
HTML
file and they each define global variables of the same name, they will
conflict with each other and cause unpredictable behavior.
let x = 3; let y = 4; function f() { x++; }
(function() { "use strict"; let x = 3; let y = 4; function f() { x++; } })();
Minimize Global and Module-Global Variables
Avoid global variables as much as possible. If you use the module pattern, your code should declare 0 global variables. Even when using the module pattern, you should try to minimize the number of "module-global" variables that are declared at the outermost scope within your anonymous wrapper function.
// global variables: avoid these at all costs let globalBad = 123; // bad let globalBad2 = 456; // bad (function() { "use strict"; // module-global variables: some are okay, but don't over-use let x = 7; let y = 8; function f() { // local variables: these are great! let z = 9; } })();
Avoid DOM Objects as Globals
Do not store DOM elements, such as those returned by the
document.getElementById
or document.querySelectorAll
functions, into global or module-global variables. Every time that you need them
in a function, call the appropriate "get" function locally.
let inputBox = document.getElementById("passwordbox"); function f1() { inputBox.value = "cuttlefish"; } function f2() { inputBox.value = "musk deer"; }
function f1() { let inputBox = document.getElementById("passwordbox"); inputBox.value = "giraffe"; } function f2() { let inputBox = document.getElementById("passwordbox"); inputBox.value = "horse"; } // alternative function f1() { document.getElementById("passwordbox").value = "giraffe"; } function f2() { document.getElementById("passwordbox").value = "horse"; }
Other Global Variable Hacks
Some students try other bizarre hacks to basically achieve global variables. For
example, you can stuff various variables and values as dynamically-created fields
inside global DOM objects such as the document
object, or you can
store anything into the global localStorage
array. In general, such
trickery should be avoided, and global DOM objects should not be abused as a way
around declaring global variables.
Minimize Code Redundancy
If you repeat the same code two or more times, find a way to remove the redundant code so that it appears only once. For example, place it into a helper function that is called from both places. If the repeated code is nearly but not entirely the same, try making your helper function accept a parameter to represent the differing part.
foo(); x = 10; y++; ... foo(); x = 15; y++;
helper(10); helper(15); ... function helper(newX) { foo(); x = newX; y++; }