Maintainable Javascript Part One

Last two days I just have finished the book 《Maintainable Javascript》.

When you come to work, you're not writing code for you, you're writing code for those who come after you.

I really like the words above the author Nicholas C. Zakas said, and this book really improves someone who may not work in professional team like me, or someone who wants to organize a team.The following is just my note that I regard it useful, but it may not really meets you.

Part one :Style Guidelines

Programs are meant to be read by humans and only incidentally for computers to execute.

null

null should be used in just a few cases:

  1. To initialize a variable that may later be assigned an object value
  2. To compare against an initialized variable that may or may not have an object value.
  3. To pass into a function where an object is expected
  4. To return from a function where an object is expected

And the best way to think about null is as a placeholder for an object.

for-in loop

As for-in loop returns not only instance properties of an object but also all properties it inherits through the prototype.Hence, it is best to filter the for-in loop to only instance properties by using hasOwnProperty().

var prop;
for (prop in object) {
    if (object.hasOwnProperty(prop)) {
        console.log("Property name is" + prop);
        console.log("Property value is" + object[prop]);
    }
}

And remember do not use for-in to iterate over members of an array.

Equality

One of the main areas in which type coercion occurs is with the use of equality operators, == and !=.

And other points in this part I just easily skip.

Part two :Programming Practices

Loose Coupling of UI Layers

Loose coupling is achieved when you are able to make changes to a single component without making changes to other components. And it is achieved by limiting each component's knowledge of the larger system.

  • Keep JavaScript Out of CSS (css expression denied)
  • Keep CSS Out of JavaScript
  • Keep JavaScript Out of HTML
// ugly code
<button onclick="doSomething()" id="action-btn">Click Me</button>
// use JavaScript methods for adding event handlers
function addListener(target, type, handler) {
    if (target.addEventListener) {
        target.addEventListener(type, handler, false);
    } else if (target.attachEvent) {
        target.attachEvent("on" + type, handler);
    } else {
        target["on" + type] = handler;
    }
}
var btn = document.getElementById("action-btn");
addListener(btn, "click", doSomething);
  • Keep HTML Out of JavaScript
// Bad 
var div = document.getElementById("my-div");
div.innerHTML = "<h3>Error</h3><p>Invalid e-mail address.</p>";

Embedding HTML strings inside your JavaScript is a bad practice for a number of reasons.And there are several ways to accomplish this in a loosely coupled manner.

1.Load from the Server

keep the templates remote and use an XMLHttpRequest object to retrieve additional markup, it is much more convenient for single-page applications than multiple-page applications. But when using this method, you should pay attention to XSS attack, and it requires lots of transcode and decode strategy between client and server to defense.

function loadDialog(name, oncomplete) {
    var xhr = new XMLHttpRequest();
    xhr.open("get", "/js/dialog/" + name, true);

    xhr.onreadystatechange = function() {

        if (xhr.readyState == 4 && xhr.status == 200) {

            var div = document.getElementById("dlg-holder");
            div.innerHTML = xhr.responseText;
            oncomplete();

        } else {
            // wrong handler
        }
    };

    xhr.send(null);
}

2.Simple Client-Side Templates

Client-side Templates are markup pieces with slots that must be filled by JavaScript in order to be complete.For example:

<li><a href="%s">%s</a></li>

And you can make templates accessible to Javascript by embedding them directly in the HTML page.Maybe a function will make it.

function sprintf(text) {
    var i = 1, args = arguments;
    return text.replace(/%s/g, function() {
        return (i < args.length) ? args[i++] : "";
    });
}

// usage
var result = sprintf(templateText, "/item/4", "Fourth item");

It is ok to include the templates as an comment or embed templates into an HTML page by using a <script> element with a custom type property.

// comment
<ul id="mylist"><!--<li id="item%s"><a href="%s">%s</a></li>-->
</ul>
/* script element, remember to strip any leading white space 
that may be in the template, because template text is  
on the line after the opening script tag */
<script type="text/x-my-template" id="list-item">
    <li><a href="%s">%s</a></li>
</script>

3.Complex Client-Side Templates

Complex Client-Side Templates may do some escaping, well, you can use some robust templates like Handlebars, which is a complete client-side templating system designed to work with JavaScript in the browser.

Maintainable Javascript Part One over.