Style Guide

These are the general style qualities that we expect your web pages to have in order to receive full credit. Certainly it is possible to write good code that violates these guidelines, and you may feel free to contact us if you are unclear about or disagree with some of them. But we do expect you to follow these rules (unless there is an error in this document). In most professional work environments you are expected to follow that company's style standards. Learning to carefully obey a style guide, and writing code with a group of other developers where the style is consistent among them, are valuable job skills.

This document is a work in progress. Any guidelines written here are in addition to what is mentioned in the given assignment's spec, so you are responsible for reading that spec and following its instructions.
Last updated Mon 2013/04/04

Languages:


HTML
  • indenting: Increase your indentation by one increment (one tab, or four spaces, etc., consistently) every time you open a new block-level element, and decrease it once each time you close a block element.

  • line breaks: Place a line break after every block element. Do not place more than one block element on the same line.

    <!-- bad -->
    <p>Hello, how are you</p>  <p>I am fine</p>
    
    <!-- good -->
    <p>Hello, how are you</p>
    <p>I am fine</p>
    
  • long lines: We permit long lines, but never begin a block element past character index 100 on a given line. When any line is longer than 100 characters and you need to begin a new block element, break it into two lines by pressing Enter after a token and resuming on the next line.

  • blank lines: Place a blank line between sections of the page and between large elements containing a lot of content.

  • elements: Do not place whitespace between a tag's < brace and the element name.

    < p >
    
    <p>
    
  • self-closing tags: End them with a space, followed by />.

    <br>
    
    <br />
    
  • choosing semantic tags: Choose appropriate tags that represent the semantic meaning of the content. For example, do not use a <p> tag around something that is not a paragraph, or do not use a <h4> unless you have already previously used h1-h3 for three other more important levels of headings, or do not use a blockquote just because you want some non-quote content to be indented to the right.

  • closing tags: You should close ALL tags, unless they are self-closing. For example, every <p> should have a corresponding </p>, and every <li> should have a corresponding </li>. Note that the HTML5 validator does not require this, but we do.

    <p>first paragraph
    <p>second paragraph
    <ul>
        <li>first item
        <li>second item
        <li>third item
    </ul>
    
    <p>first paragraph</p>
    <p>second paragraph</p>
    <ul>
        <li>first item</li>
        <li>second item</li>
        <li>third item</li>
    </ul>
    
  • nesting: Close tags in the opposite order in which they were opened. Always nest every inline element inside of a block element. (For example, don't just put an <a> tag directly inside the body; instead, place it inside a p or li or other block-level element.

  • presentational tags: Do not ever use deprecated tags whose meaning is entirely based on their appearance, such as b, i, u, big, small, center, or font. (Use CSS instead to achieve such an appearance.)

  • attributes: Do not place a space between an attribute's name, the equals sign, and its value. Enclose the value in " " quotes, not bare, and not in ' ' apostrophes.

    <a href = 'foo.html'>
    
    <a href="foo.html">
    
  • boolean attributes: For attributes that are essentially boolean flags, set them equal to themselves.

    <input type="text" disabled />
    
    <input type="text" disabled="disabled" />
    
  • img tag alt attribute: Every img tag must have an alt attribute so that it can be understood by visually impaired users.

    <img src="kittens.jpg" />
    
    <img src="kittens.jpg" alt="a long cat" />
    
  • names: When giving an element an id or class, give it a descriptive name, such as mainheading or announcements. Avoid one-letter names like x or c.

  • capitalization: Always favor lowercase, for elements, for attributes and their values, for classes and ids. Multi-word names for classes and ids should simply concatenate the words in lowercase without any in-between character (such as _) and without capitalization of the next word.

    <h1 id="first_heading">
    <P Class="importantReminder">
    
    <h1 id="firstheading">
    <p class="importantreminder">
    
  • class vs. id: Choose appropriately between classes and ids. If an element belongs to a general category that can include multiple elements, use a class. If it is a unique part of the page that deserved to be named on its own, use an id.

  • class-itis and id-itis: Do not over-use classes and ids on elements that do not need them. If an equivalent style can be described cleanly using a CSS context selector such as .announcements li > strong rather than a class or id, consider doing that instead. A class or id is still more appropriate than a context selector if the context is very complicated or not really related to the styling.

  • tables for layout: Do not use HTML table tags to lay out the contents of a web page. For example, it is inappropriate to use a table to divide the page's main content sections into columns, or to get a sidebar or navigation bar, etc. Instead, use div and other related tags along with the CSS box model and the float property as appropriate. See Chapter 4 of the Web Programming Step by Step textbook for examples.

  • inline css styles: Should never be used. All CSS styles should be specified within a .css file and never as part of an HTML tag with the style attribute.

CSS
  • whitespace: Place a line break after a { or }, and between each property declaration. Place spaces between selectors and { }. Place a space after a colon or a comma. Place a semicolon after every property declaration.

    p,h1{color:red; font-family:serif; font-size:16pt;}
    a {text-decoration:none}
    
    a {
        text-decoration: none;
    }
    
    h1, p {
        color: red;
        font-family: serif;
        font-size: 16pt;
    }
    
  • property order: Alphabetize the order of the properties of every style rule, always. As much as is reasonable, also alphabetize the order of selectors in a rule that contains more than one selector (like with h1 and p below).

    p, h1 {
        font-size: 16pt;
        text-decoration: underline;
        font-family: serif;
        color: red;
    }
    
    h1, p {
        color: red;
        font-family: serif;
        font-size: 16pt;
        text-decoration: underline;
    }
    
  • minimize redundant CSS: If you repeat the same styles two or more times, and the styles are related in some way, find a way to remove the redundant code so that it appears only once. For example, place it into a common style rule that is used in both places. Note that not every common style should be combined; if two completely unrelated tags happen to share a style attribute (such as both being bold), this does not necessarily mean that they should be combined. A good example of when styles should be combined is if a site has a common font or color scheme that is used on several elements. The style should be written once and used throughout the page so it can be changed easily later if needed.

    p {
        font-family: "Comic Sans MS", sans-serif;
    }
    h1 {
        font-family: "Comic Sans MS", sans-serif;
    }
    
    h1, p {
        font-family: "Comic Sans MS", sans-serif;
    }
    
  • avoid unnecessary CSS rules: If a rule is not ever used in the page, remove it from your CSS file.

  • "vendor prefixed" CSS rules: Some CSS3 properties have browser-specific versions with prefixes like -webkit- and -moz-. Do not use these vendor-specific properties in your homework assignments unless you are specifically granted permission to do so.

    div {
        -webkit-border-radius: 10px;
    }
    
    div {
        border-radius: 10px;
    }
    
PHP
  • HTML in .php files: All HTML content that is inside of .php files is subject to the HTML style guide posted on this web site.

  • HTML validation: All HTML pages sent as output from a PHP file should pass the HTML validator. Choose the "View Source" option in your browser to get the HTML output, then copy/paste this into the validator.

  • switching between PHP and HTML modes: Try to minimize the number of unnecessary switches between PHP mode and HTML output mode. In particular you should never switch modes and then immediately switch back again, back to back, such as ?> <?php or <?php ?> <?php.

  • expression blocks: Expression blocks should be used to inject PHP variables and values into HTML output. You should never call a PHP function from within an expression block, unless that function returns a value you want to print.

  • blank lines: Place a blank line before each mode switch from PHP mode to HTML mode. Also place blank lines before or after functions and between complex sections of code. (Of course, PHP expression blocks in <?= ... ?> do not require blank lines around them.) Never place more than one PHP statement on the same line.

  • indentation and whitespace: Increase your indentation by one increment (one tab, or four spaces, etc., consistently) every time you open a new left curly brace {, and decrease the indent on each right curly brace }. Also indent by one increment on each opening tag and decrease it on each closing tag. Therefore your PHP and HTML blocks should have a mixed indentation shared between the two of them, such as:

    <div>
        <ul>
            
            <?php
            $max = 10;
            for ($i = 0; $i < $max; $i++) {
                ?>
                
                <li> There are <?= $i ?> bottles of beer on the wall.</li>
                
                <?php
            }
            ?>
            
        </ul>
    </div>
    
    The indentation shown in class examples (opening and closing PHP blocks at the same level of indentation) is also acceptable.
  • condensed whitespace: It is acceptable to enter-and-exit PHP mode on the same line, but only for an individual statement such as an if/else or loop header, or a single function call. If you use this condensed syntax, it is acceptable to omit blank lines around the mode switch.

    <ul>
        <?php for ($i = 0; $i < 10; $i++) { ?>
            <li> There are <?= $i ?> bottles of beer on the wall. </li>
        <?php } ?>
    </ul>
    
  • long lines: Lines of pure PHP code (in PHP mode) should not exceed 100 characters in length. Lines of HTML content inside a PHP file (in HTML mode) are subject to the HTML section of the style guide in terms of line length.

  • print / echo statements: They should never be used in our assignments unless you are writing a web service. Instead, mode-switch into HTML output mode and write the content you want to display.

  • commenting placement/contents: Every PHP file should have a descriptive comment header at the top, written in your own words. Every function must have a comment header describing the function's behavior and parameters/return as appropriate. Non-trivial or complex sections of code (such as a piece of code that reads and processes an input file) should also have a brief comment explaining the code's purpose.

  • comment syntax: Be sure to choose the right comment syntax. Many students try to use HTML-style <!-- ... --> comments in their PHP code files. If the comments are about HTML content/output, then that comment syntax is appropriate. But if you are commenting about PHP code, such as the purpose of a function or complex section of code, you should favor PHP-style # or // or /* ... */ comment syntax. As a general rule, most of your comments should use the PHP syntax except for occasional ones that are specifically about HTML output tags.

  • variable "declarations": PHP has no concept of "declaring" a variable without initializing it. A statement such as the following is useless and should not be included in your code.

    # bad
    $employees;        # these statements do nothing;
    $todays_date;      # they do not actually declare variables
    
  • names: When declaring a variable or function, give it a descriptive name, such as $students or $ostrich_count. Avoid one-letter names like $x or $c.

  • capitalization: Name variables and functions in lowercase, with underscores to separate words, such as $ostrich_count or compute_student_grade. If a variable serves as a de-facto constant, name it in uppercase, such as $INTEREST_RATE.

  • function placement: Place all of your functions at the very top or bottom of your PHP file, never in the middle of the page.

  • global keyword vs. function parameters/return: You should never use the global keyword, which allows functions to have access to global variables. Instead, pass parameters to the function and/or return a value from the function.

    # bad
    $students = 4;
    $money = 2;
    process_classroom();
    ...
    function process_classroom() {
        global $students;
        global $money;
        print($students);
        $money = 5;
    }
    
    # good
    $students = 4;
    $money = 2;
    $money = process_classroom($students);
    ...
    function process_classroom($stud) {
        print($stud);
        return 5;
    }
    
  • referring to array elements: If your code processes an array where each element has a specific unique meaning, such as when exploding the tokens of a line of an input file, you should unpack that array into individual variables and avoid referring to array elements by their indexes as much as possible. The reason to give them variable names is because the names are more descriptive and understandable than just using numeric indexes. One convenient way to unpack an array into variables is to use the list function.

    # bad
    $tokens = explode(":", $line);
    if ($tokens[4] > $tokens[2] && $tokens[3] != "quit") {
        ...
    }
    
    # good
    list($name, $id, $age, $action, $maxage) = explode(":", $line);
    if ($maxage > $age && $action != "quit") {
        ...
    }
    
  • It is sometimes okay to refer to elements of a super-global array, such as $_GET or $_COOKIE. The indexes of an associative array are strings, which are often more descriptive names than numeric array indexes. But if you use the value from the super-global several times, you should still pull it out into a variable.

    # bad
    if (strlen($_POST["studentname"]) >= 5 &&
        $_POST["studentname"] != "guest") {
        ...
    }
    
    # good
    $name = $_POST["studentname"];
    if (strlen($name) >= 5 && $name != "guest") {
        ...
    }
    
  • superglobals are read-only: The super-global arrays like $_GET, $_POST, and $_SERVER should be considered read-only. You should not store new values in them or modify existing values in them as a way of avoiding using regular local variables. (The $_SESSION superglobal array is an exception to this rule, if the assignment involves managing user login sessions. It is meant to be written into directly by your code.)

  • redundancy: You should work hard to reduce the amount of redundant PHP code in your programs. This includes several kinds of redundancy elimination, such as moving repeated code into a loop, creating a function containing redundant code, or include-ing a shared page of common HTML and/or PHP content.

  • save expensive call results in a variable: If you are calling an expensive function and using its result multiple times, save that result in a variable rather than having to call the function multiple times.

    # bad
    if (strlen(file_get_contents("foo.txt")) >= 0 &&
            file_get_contents("foo.txt") != "hello") {
        $text = strtolower(file_get_contents("foo.txt"));
    }
    
    # good
    $text = file_get_contents("foo.txt");
    if (strlen($text) >= 0 && $text != "hello") {
        $text = strtolower($text);
    }
    
  • if/else factoring: Move common code out of if/else statements so that it is not repeated.

    # bad
    if ($x < $y) {
        foo();
        $x++;
        print("hi");
    } else {
        foo();
        $y++;
        print("hi");
    }
    
    # good
    foo();
    if ($x < $y) {
        $x++;
    } else {
        $y++;
    }
    print("hi");
    
  • for vs while: Use a for or foreach loop when the number of repetitions is known (definite); use a while loop when the number of repetitions is unknown (indefinite).

  • break and continue: In general, you should avoid using the break or continue statements in loops unless absolutely necessary.

  • if/else patterns: When using if/else statements, properly choose between various if and else patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if tests.

    # bad
    if ($grade >= 90) {
        print("You got an A!");
    }
    if ($grade >= 80 && $grade < 90) {
        print("You got a B!");
    }
    if ($grade >= 70 && $grade < 80) {
        print("You got a C!");
    }
    ...
    
    # good
    if ($grade >= 90) {
        print("You got an A!");
    } else if ($grade >= 80) {
        print("You got a B!");
    } else if ($grade >= 70) {
        print("You got a C!");
    }
    ...
    
  • boolean zen 1: If you have an if/else statement that returns a boolean value based on a test, just directly return the test's result instead.

    # bad
    if ($score1 == $score2) {
        return TRUE;
    } else {
        return FALSE;
    }
    
    # good
    return $score1 == $score2;
    
  • boolean zen 2: Don't ever test whether a boolean value is == or != to TRUE or FALSE.

    # bad
    if ($x == TRUE) {
        ...
    } else if ($x != TRUE) {
        ...
    }
    
    # good
    if ($x) {
        ...
    } else {
        ...
    }
    
SQL
  • filtering rows with WHERE: Queries should properly filter out rows that are not of interest to your code. For example, if you are looking for cities with a large population, you might choose to fetch all cities and loop over them in your code, displaying only the ones with large population. Instead, you should rely on the database to filter out the rows using a proper WHERE clause.

    -- bad
    SELECT * FROM cities;
    
    -- good
    SELECT * FROM cities WHERE population > 500000;
    
  • filtering rows with LIMIT: If you are only interested in a small number of results of your query, use a LIMIT clause to ensure that your query only returns that many rows. For example, if you wanted the 3 cities with the highest population in the entire database:

    -- bad
    SELECT * FROM cities ORDER BY population DESC;
    
    -- good
    SELECT * FROM cities ORDER BY population DESC LIMIT 3;
    
  • filtering columns with SELECT: If you are only interested in certain columns from your query, use a SELECT clause that lists only the columns of interest. This saves the database some work and memory over always selecting *. For example, if you wanted only the names and populations of the 3 cities with the highest population in the entire database:

    -- bad
    SELECT * FROM cities ORDER BY population DESC LIMIT 3;
    
    -- good
    SELECT name, population FROM cities ORDER BY population DESC LIMIT 3;
    
  • line breaks in long queries: If your query is more than ~80-100 characters in length, split it into multiple lines. You can do this in bare SQL or also in PHP, because PHP allows bare line breaks within a string.

    -- bad
    SELECT name, population, district FROM cities WHERE population > 500000 ORDER BY district, population, name DESC LIMIT 3;
    
    -- good
    SELECT name, population, district
    FROM cities
    WHERE population > 500000
    ORDER BY district, population, name DESC
    LIMIT 3;
    
    # PHP query
    $rows = $db->query("SELECT name, population, district
                        FROM cities
                        WHERE population > 500000
                        ORDER BY district, population, name DESC
                        LIMIT 3");
    
  • proper JOIN ... ON condition: If your query uses data from multiple tables, use one or more JOIN clauses to connect them. Always join properly by relating unique keys from one table with those of another in your JOIN ... ON condition. Any other filters or constraints on the data that are not related to connecting keys of joined tables should go in the WHERE clause.

    -- bad
    SELECT c.name
    FROM courses c
    JOIN grades g ON g.course_id = c.id
    JOIN students bart ON bart.name = 'Bart'
    WHERE g.student_id = bart.id;
    
    -- good
    SELECT c.name
    FROM courses c
    JOIN grades g ON g.course_id = c.id
    JOIN students bart ON g.student_id = bart.id
    WHERE bart.name = 'Bart';
    
  • JOIN ... ON vs. FROM/WHERE: It is possible to write an equivalent query with a FROM and WHERE clause that is equivalent to a JOIN but does not use JOIN syntax. For the purposes of this course, such a query would be considered poor style and should be avoided.

    -- bad
    SELECT c.name
    FROM courses c, grades g, students s
    WHERE bart.name = 'Bart'
    AND g.student_id = bart.id
    AND g.course_id = c.id;
    
    -- good
    SELECT c.name
    FROM courses c
    JOIN grades g ON g.course_id = c.id
    JOIN students bart ON g.student_id = bart.id
    WHERE bart.name = 'Bart';
    
  • quoting inserted parameters: To avoid SQL injection and security risks, any SQL query that inserts user input into the query string as a parameter must properly SQL-encode that parameter using a function such as PDO's quote method.

    $student = $_GET["student"];
    $rows = $db->query("SELECT c.name
                        FROM courses c
                        JOIN grades g ON g.course_id = c.id
                        JOIN students bart ON g.student_id = bart.id
                        WHERE bart.name = '$student');
    
    $student = $_GET["student"];
    $student = $db->quote($student);
    $rows = $db->query("SELECT c.name
                        FROM courses c
                        JOIN grades g ON g.course_id = c.id
                        JOIN students bart ON g.student_id = bart.id
                        WHERE bart.name = $student);
    
  • commenting a query: Any program that performs a SQL query should contain a brief comment next to that query indicating the meaning and purpose of the query. The comment can be in SQL syntax (using the -- prefix at the start of the line) but more likely should be in the syntax of the programming language containing the query, such as PHP.

    -- retrieves the names of all courses Bart Simpson has taken
    SELECT c.name
    FROM courses c
    JOIN grades g ON g.course_id = c.id
    JOIN students bart ON g.student_id = bart.id
    WHERE bart.name = 'Bart';
    
    # query to retrieve the names of all courses Bart Simpson has taken
    $rows = $db->query("SELECT c.name
                        FROM courses c
                        JOIN grades g ON g.course_id = c.id
                        JOIN students bart ON g.student_id = bart.id
                        WHERE bart.name = 'Bart');
    
JavaScript
  • frameworks (e.g. jQuery): Please follow any restrictions in your assignment spec about the use of external JavaScript libraries such as jQuery. If the spec forbids using such libraries, do not link to them or use them in your code. These libraries can be very useful and powerful, but in a course setting, sometimes the assignment is intended to be solved without the use of these tools.

  • unobtrusive JavaScript: Always use unobtrusive JavaScript to keep all JavaScript commands entirely out of your HTML code 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.

    <!-- bad (HTML) -->
    <button onclick="foo();">Click Me</button>
    
    // bad (JS)
    function foo() {
        alert("You clicked the button.");
    }
    
    <!-- good (HTML) -->
    <button id="clickme">Click Me</button>
    
    // good (JS)
    window.onload = function() {
        document.getElementById("clickme").onclick = foo;
    };
    
    function foo() {
        alert("You clicked the button.");
    }
    
  • use strict: Always write a "use strict"; declaration at the top of your JS file to tell the browser to enable strict syntax checking of your JavaScript code.

  • JSLint: All of your JS files must pass the provided JSLint tool with zero errors. JSLint "warnings" or "notices" are less serious messages; it is okay to have these in your code.

  • module pattern: Always use the "module pattern" of wrapping your JS file's code inside an anonymous function that is immediately invoked, to get rid of global variables.

    // bad
    var x = 3;
    var y = 4;
    
    function f() {
        x++;
    }
    
    // good
    (function() {
        "use strict";
    
        var x = 3;
        var 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
    var globalBad = 123;      // bad
    var globalBad2 = 456;     // bad
    
    (function() {
        "use strict";
    
        // module-global variables: some are okay, but don't over-use them
        var x = 7;
        var y = 8;
    
        function f() {
            // local variables: these are great!
            var z = 9;
        }
    })();
    
  • DOM objects as globals: Do not store DOM element objects, 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.

    // bad
    var inputBox = document.getElementById("passwordbox");
    
    function f1() {
        inputBox.value = "giraffe";
    }
    function f2() {
        inputBox.value = "horse";
    }
    
    // good
    function f1() {
        var inputBox = document.getElementById("passwordbox");
        inputBox.value = "giraffe";
    }
    function f2() {
        var 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.

  • anonymous functions: Anonymous functions are useful and expressive in some cases where a function's name is meaningless and cumbersome, such as an initial window.onload handler. But over-using anonymous functions leads to code that is too heavily nested and has too few names to guide the programmer, so over-use of anonymous functions should be avoided. In general, give names to your functions unless the name is truly useless and meaningless.

    // bad
    window.onload = function() {
        myButton.onclick = function() {
            setTimeout(function() {
                alert("hi!");
            }, 1000);
        };
    }
    
    // good
    window.onload = function() {
        myButton.onclick = myButtonClick;
    }
    
    function myButtonClick() {
        setTimeout(displayHiMessage, 1000);
    }
    
    function displayHiMessage() {
        alert("hi!");
    }
    
  • setting styles in JS code: If you are setting several styles on a DOM object in JS code, instead declare a class in your CSS file and use the JS code to apply that class to the DOM object. This helps keep most of the style decisions in your CSS file where they belong and out of your JS code.

    // bad (JS)
    myButton.style.border = "2px dotted green";
    myButton.style.color = "red";
    myButton.style.fontSize = "20pt";
    myButton.style.fontWeight = "bold";
    myButton.style.textDecoration = "underline";
    
    /* good (CSS) */
    button.urgent {
        border: 2px dotted green;
        color: red;
        font-size: 20pt;
        font-weight: bold;
        text-decoration: underline;
    }
    
    // good (JS)
    myButton.className = "urgent";
    
  • semicolons: JavaScript often still works if semicolons are omitted, using complex logic called automatic semicolon insertion (ASI). But you should not rely on this and should always insert semicolons wherever you end a complete statement of code.

    // bad
    var x = 3
    var y = 4
    
    function foo() {
        alert("hi!");
    }
    
    window.onload = function() {
        x++
        foo()
    }
    
    // good
    var x = 3;
    var y = 4;
    
    function foo() {
        alert("hi!");
    }
    
    window.onload = function() {
        x++;
        foo();
    };
    
  • indenting: Increase your indentation by one increment on each brace {, and decrease it once on each closing brace }.

  • line breaks: Place a line break after every { . Do not place more than one statement on the same line.

    // bad
    var x = 3;  var y = 4;  x++;
    if (a == b) { foo(); }
    
  • long lines: When any line is longer than 100 characters, break it into two lines by pressing Enter after an operator and resuming on the next line. Indent the trailing second part of the line by two increments (e.g. two tabs). For example:

    var result = reallyLongFunctionOne() + reallyLongFunctionTwo() + 
            reallyLongFunctionThree() + reallyLongFunctionFour();
    
    var result2 = reallyLongFunction(parameterOne, parameterTwo, parameterThree,
            parameterFour, parameterFive, parameterSix);
    
  • expressions: Place a space between operators and their operands.

    var x = (a + b) * c / d + foo();
    
  • blank lines: Place a blank line between functions and between groups of statements.

    function foo() {
        ...
    }
                              // this blank line here
    function bar() {
        ...
    }
    
  • names: Give variables descriptive names, such as firstName or homeworkScore. Avoid one-letter names like x or c, except for loop counter variables such as i.

  • capitalization: Name variables and functions with camel-casing likeThis, name classes with Pascal casing LikeThis, and name unchanging "constant" variables in uppercase LIKE_THIS.

  • scope: Declare variables in the narrowest possible scope. For example, if a variable is used only inside a specific if statement, declare it inside that if statement rather than at the top of the function or at the top of the class.

  • constants: If a particular constant value is used frequently in your code, declare it as a module-global "constant" variable in uppercase, and always refer to the constant in the rest of your code rather than referring to the corresponding value.

    var DRINKING_AGE = 21;
    
  • for vs while: Use a for loop when the number of repetitions is known (definite); use a while loop when the number of repetitions is unknown (indefinite).

    // repeat exactly size/2 times
    for (var i = 0; i < size / 2; i++) {
        ...
    }
    
    // repeat until the user clicks OK
    while (!confirm("Are you sure?")) {
        ...
    }
    
  • break and continue: In general, you should avoid using the break or continue statements in loops unless absolutely necessary.

  • if/else patterns: When using if/else statements, properly choose between various if and else patterns depending on whether the conditions are related to each other. Avoid redundant or unnecessary if tests.

    // bad
    if (grade >= 90) {
        alert("You got an A!");
    }
    if (grade >= 80 && grade < 90) {
        alert("You got a B!");
    }
    if (grade >= 70 && grade < 80) {
        alert("You got a C!");
    }
    ...
    
    // good
    if (grade >= 90) {
        alert("You got an A!");
    } else if (grade >= 80) {
        alert("You got a B!");
    } else if (grade >= 70) {
        alert("You got a C!");
    }
    ...
    
  • boolean zen 1: If you have an if/else statement that returns a boolean value based on a test, just directly return the test's result instead.

    // bad
    if (score1 == score2) {
        return true;
    } else {
        return false;
    }
    
    // good
    return score1 == score2;
    
  • boolean zen 2: Don't ever test whether a boolean value is == or != to true or false.

    // bad
    if (x == true) {
        ...
    } else if (x != true) {
        ...
    }
    
    // good
    if (x) {
        ...
    } else {
        ...
    }
    
  • exception handling: We don't use exceptions really in JS in this material. So in general you should avoid try/catch statements because this is not how we intend you to solve the problems. But if you do need to use one, don't ever catch an exception with an empty catch block.

    // bad
    try {
        foo();
        bar();
    } catch (npe) {}
    
  • minimize redundant code: 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.

    // bad
    foo();
    x = 10;
    y++;
    ...
    
    foo();
    x = 15;
    y++;
    
    // good
    helper(10);
    helper(15);
    ...
    
    function helper(newX) {
        foo();
        x = newX;
        y++;
    }
    
  • if/else factoring: Move common code out of if/else statements so that it is not repeated.

    // bad
    if (x < y) {
        foo();
        x++;
        alert("hi");
    } else {
        foo();
        y++;
        alert("hi");
    }
    
    // good
    foo();
    if (x < y) {
        x++;
    } else {
        y++;
    }
    alert("hi");
    
  • function structure: If you have a single function that is very long, break it apart into smaller sub-functions. The definition of "very long" is vague, but let's say a function longer than 20-30 lines is pushing it. If you try to describe the function's purpose and find yourself using the word "and" a lot, that probably means the function does too many things and should be split into sub-functions.

  • save expensive call results in a variable: If you are calling an expensive function and using its result multiple times, save that result in a variable rather than having to call the function multiple times.

    // bad
    if (list.indexOf("abc") >= 0) {
        list.remove(list.indexOf("abc"));
    }
    
    // good
    var index = list.indexOf("abc");
    if (index >= 0) {
        list.remove(index);
    }
    
JavaScript Framework: jQuery
  • Usage: When explicitly allowed by the homework specification, you can use jQuery, but we expect your Javascript to be written in the style of the jQuery framework. There are many many bad resources for jQuery so be careful how you Google, below are the best style practices for the most common jQuery actions, if you have style questions on other features feel free to post on the message board.

  • Function calls: They SHOULD be chained when possible, most jQuery calls return the original object so they can be chained appropriately. Chained method calls should be on their own line for readability

    // bad
    var obj = $("#selected").callOne();
    obj = obj.callTwo();
    obj = obj.callThree();
    obj = obj.callFour();
    
    // good
    var obj = $("#selected").callOne()
                            .callTwo()
                            .callThree()
                            .callFour();
    
  • Global functions: When calling a global function (e.g. post, ajax)you should call the $ object instead of the jQuery object.

    // bad
    jQuery.globalFunction();
    
    // good
    $.globalFunction();
    
  • Document onload: When using jQuery it is incorrect to specify listeners directly on the window or document object. Instead you should use the ready event listener. Note that for page loads you should always use ready and not load

    // bad
    window.onload = pageReadyHandler;
    
    // good
    $(document).ready(pageReadyHandler);
    
  • CSS properties: All CSS properties should be accessed and set via the css() method

  • Nested selectors: It is better to use find than to nest when possible, this is because the sizzle engine that is internal to jQuery can optimize these calls more.

    // bad
    var children = $("#overallDiv .subClass");
    
    // good
    var children = $("#overallDiv").find(".subClass");
    
  • Manipulating page content: If jQuery provides a method to manipulate a value or attribute it should be used instead of manually manipulating things. Here is a non-exhaustive list of examples:

    • When adding HTML content to the page you should use html() instead of innerHTML
    • When creating content nodes you should use append() to add it to the page
    • When getting/setting text you should use text() instead of attributes like textContent
    • When getting/setting input values you val() instead of the value attribute
  • Avoid looping when possible: Most jQuery result objects can apply calls to every value in the returned set and this should be used instead of looping over the results

    // bad
    var results = $('.findMe');
    for(var i = 0; i < results.length; i++) {
    	results.css({ "color" : "red" });
    }
    
    // good - jQuery knows to apply it to everything
    $('.findMe').css({ "color" : "red" });
    
  • Attaching events: jQuery provides a number of named event methods like click() or mouseover(), when attaching events to objects these should be preferred over manual bindings. If no named method exists the bind() method should be used.

  • Detaching events: To detach you must use the unbind() method, no other method will completely unregister your event handlers and this may cause adverse side effects.

  • AJAX requests: You should use the specific $.get and $.post methods when possible, falling back to $.ajax when the request type is dynamically determined. In addition all parameters should be sent via a data object instead of directly in the url

    // bad
    $.ajax({
    	url : "service.php?param1=data1&param2=data2",
    	type : "GET"
    	...
    })
    
    // good
    $.get({
    	url : "service.php",
    	data : {
    		param1 : data1,
    		param2 : data2
    	}
    	...
    })
    
JavaScript Framework: Prototype
  • Usage: When explicitly allowed by the homework specification, you can use Prototype, but we expect your Javascript to be written in the style of the Prototype framework. Below are the best style practices for the most common Prototype actions, if you have style questions on other features feel free to post on the message board.

  • Querying for ids: You should use the provided $ object instead of document.getElementById

  • Querying with css selectors: You should use the provided $$ object instead of document.querySelector[All]

  • Querying for form controls: You should use the provided $F when querying for form controls

  • Manipulating content: Instead of looping over a result set form Prototype to apply a function, you should take advantage of the special invoke function that is added to result sets.

    // bad
    var results = $$('.findMe');
    for(var i = 0; i < results.length; i++) {
    	results.hide();
    }
    
    // good
    $$('.findMe').invoke('hide')
    
  • AJAX requests: Ajax requests should be sent using the Ajax.Request object instead of the XMLHttpRequest. Responses will be automatically decoded by this library so you won't need functions like JSON.parse

  • Animations: Any animations should be done via the Effects object that is part of prototype. More complex animations should use the extended library scriptaculous

Comments
  • file header: Place a descriptive comment heading on the top of every file describing that file's purpose. Assume that the reader of your comments is an intelligent programmer but not someone who has seen this assignment before. Your comment header should include at least your name, course/section, and a brief description of the assignment. If the assignment asks you to submit multiple files, each file's comment header should describe that file/class and its main purpose in the program.

  • function headers: Place a comment heading on each function you declare. The heading should describe the function's behavior.

  • parameters/return: If your function accepts parameters, briefly describe their purpose and meaning. If your function returns a value, briefly describe what it returns.

  • inline comments: Inside the interiors of your various functions, if you have sections of code that are lengthy or complex or non-trivial, place a small amount of inline comments near these lines of complex code describing what they are doing.

  • implementation details: Comment headers at the top of a function or class should describe the function's behavior, but not great detail about how it is implemented. Do not mention language-specific details like the fact that the function uses a if/else statement, that the function declares an array, that the function loops over a collection and counts various elements, etc.

  • wording: Your comment headers should be written in complete sentences, and should be written in your own words, not copied from other sources (such as copied verbatim from the homework spec document).

  • commented-out code: It is considered bad style to turn in a program with chunks of code "commented out". It's fine to comment out code as you are working on a program, but if the program is done and such code is not needed, just remove it.

Valid HTML5 Valid CSS JavaScript Lint
This document and its content are copyright © Allison Obourn and Marty Stepp, 2015. All rights reserved. Any redistribution, reproduction, transmission, or storage of part or all of the contents in any form is prohibited without the author's expressed written permission.