• Shuffle
    Toggle On
    Toggle Off
  • Alphabetize
    Toggle On
    Toggle Off
  • Front First
    Toggle On
    Toggle Off
  • Both Sides
    Toggle On
    Toggle Off
  • Read
    Toggle On
    Toggle Off
Reading...
Front

Card Range To Study

through

image

Play button

image

Play button

image

Progress

1/51

Click to flip

Use LEFT and RIGHT arrow keys to navigate between flashcards;

Use UP and DOWN arrow keys to flip the card;

H to show hint;

A reads text to speech;

51 Cards in this Set

  • Front
  • Back
  • 3rd side (hint)
return statement
what a function "gives back" after it is called. The value returned can be assigned to a variable.
What are the two ways to create objects in javascript? ____"notation"and _____ "notation"
literal ({}and commas) and constructor is (New() and ;)

Literal notation is the one where we declare the object, and, at the same time, define properties and values in the object. It makes use of { }. See Line 1 for an example.

Constructor notation is where we make use of the keywords new Object(). We then use dot notation to add property and values to the object.
var australia = {
weather: "superb",
people: "not many of them but they're all great!",
tourism: "a wonderful place to holiday. please visit!"
};

var jordan = new Object();
jordan.weather = "hot. but so are the people!";
jordan.people = "see above!";
jordan.tourism = "Codecademy's dream team retreat!";
Why use object literal notation in javascript?
Object literal notation is a shorthand form of object definition designed to simplify creating an object with numerous properties
Naming Tips for javascript
The naming of variables is more art than science, but in general, you should try to make the variable names as short as possible to get the point across. Try to make the variable name indicate the data type of its value. For example, the names count, length, and size suggest the data type is a number, and names such as name, title, and message suggest the data type is a string. Single-character variable names such as i, j, and k are typically reserved for use in loops. Using names that suggest the data type makes your code easier to understand by others as well as yourself.

Meaningless names should be avoided. Names such as foo, bar, and temp, despite being part of the developer’s toolbox, don’t give any meaning to variables. There’s no way for another developer to understand what the variable is being used for without understanding all of the context.

For function and method names, the first word should always be a verb, and there are some common conventions used for that verb:

Verb Meaning
can Function returns a boolean
has Function returns a boolean
is Function returns a boolean
get Function returns a nonboolean
set Function is used to save a value
Pascal Case
Pascal case is the same as camel case except that the initial letter is uppercase. So instead of anotherName, you would use AnotherName.
JavaScript constructors
Constructors
JavaScript constructors are simply functions that are used to create objects via the new operator. The language contains many built-in constructors, such as Object and RegExp, and developers can add their own constructors to create new types. As with other naming conventions, constructors follow the native language, so constructors are formatted using Pascal case.

Pascal case is the same as camel case except that the initial letter is uppercase. So instead of anotherName, you would use AnotherName. Doing so helps to differentiate constructors from both variables and nonconstructor functions. Constructor names also are typically nouns, as they are used to create instances of a type. Here are some examples:

// Good
function Person(name) {
this.name = name;
}

Person.prototype.sayName = function() {
alert(this.name);
};

var me = new Person("Nicholas");Following this convention also makes it easier to spot errors later. You know that functions whose names are nouns in Pascal case must be preceded by the new operator. Consider the following:

var me = Person("Nicholas");
var you = getPerson("Michael");

Here, line 1 should jump out as a problem to you [needs new?], but line 2 looks okay according to the conventions already laid out in this chapter.
JavaScript constructors
functions that are used to create objects via the new operator
null versus undefined
The special value null is often misunderstood and confused with undefined. This value should be used in just a few cases:

■To initialize a variable that may later be assigned an object value

■To compare against an initialized variable that may or may not have an object value

■To pass into a function where an object is expected

■To return from a function where an object is expected

There are also some cases in which null should not be used:

■Do not use null to test whether an argument was supplied.

■Do not test an uninitialized variable for the value null.

Here are some examples:

// Good
var person = null;

// Good
function getPerson() {
if (condition) {
return new Person("Nicholas");
} else {
return null;
}
}

// Good
var person = getPerson();
if (person !== null) {
doSomething();
}

// Bad: Testing against uninitialized variable
var person;
if (person != null) {
doSomething();
}

// Bad: Testing to see whether an argument was passed
function doSomething(arg1, arg2, arg3, arg4) {
if (arg4 != null) {
doSomethingElse();
}
}The best way to think about null is as a placeholder for an object. These rules are not covered by any major style guide but are important for overall maintainability.
which is most commonly used notation for creating objects?
literal, constructor is rarely used
sample object literal notation
When defining object literals, it’s typical to include the opening brace on the first line,
then each property-value pair on its own line, indented one level, then the closing brace
on its own line. For example:
// Good
var book = {
title: "Maintainable JavaScript",
author: "Nicholas C. Zakas"
};
array literals
Array literals, as with object literals, are a more compact way of defining arrays in
JavaScript. Explicitly using the Array constructor, as in this example, is generally
frowned upon:
// Bad
var colors = new Array("red", "green", "blue");
var numbers = new Array(1, 2, 3, 4);
Instead of using the Array constructor, you can use two square brackets and include
the initial members of the array:
// Good
var colors = [ "red", "green", "blue" ];
var numbers = [ 1, 2, 3, 4 ];
[] and commas
brace alignment
have the opening brace on the same line
as the beginning of the block statement, as in this example:
if (condition) {
doSomething();
} else {
doSomethingElse();
}
for in loop
A problem with for-in is that it returns not only instance properties of an object
but also all properties it inherits through the prototype. You may thus end up with
unanticipated results when iterating through properties on your own object. For this
reason, it’s best to filter the for-in loop to only instance properties by using
hasOwnProperty(). Here’s an example:
var prop;
for (prop in object) {
if (object.hasOwnProperty(prop)) {
console.log("Property name is " + prop);
console.log("Property value is " + object[prop]);
}
}
when not to use "for in" loop
A problem with for-in is that it returns not only instance properties of an object
but also all properties it inherits through the prototype. You may thus end up with
unanticipated results when iterating through properties on your own object. For this
reason, it’s best to filter the for-in loop to only instance properties by using
hasOwnProperty(). Here’s an example:
var prop;
for (prop in object) {
if (object.hasOwnProperty(prop)) {
console.log("Property name is " + prop);
console.log("Property value is " + object[prop]);
}
}
var statements
Variable declarations are accomplished by using the var statement. JavaScript allows the var statement to be used multiple times and nearly anywhere within a script. This usage creates interesting cognitive issues for developers, because all var statements are hoisted to the top of the containing function regardless of where they actually occur in the code. For example:

function doSomething() {

var result = 10 + value;
var value = 10;
return result;
}In this code, it’s perfectly valid for the variable value to be used before it was declared, though it will cause result to have the special value NaN. To understand why, you need to be aware that this code is changed by the JavaScript engine to this:

function doSomething() {

var result;
var value;

result = 10 + value;
value = 10;

return result;
}The two var statements are hoisted to the top of the function; the initialization happens afterward. The variable value has the special value undefined when it’s used on line 6, so result becomes NaN (not a number). Only after that is value finally assigned the value of 10.

One area where developers tend to miss variable declaration hoisting is with for statements, in which variables are declared as part of the initialization:

function doSomethingWithItems(items) {

for (var i=0, len=items.length; i < len; i++) {
doSomething(items[i]);
}
}JavaScript up to ECMAScript 5 has no concept of block-level variable declarations, so this code is actually equivalent to the following:

function doSomethingWithItems(items) {

var i, len;

for (i=0, len=items.length; i < len; i++) {
doSomething(items[i]);
}
}Variable declaration hoisting means defining a variable anywhere in a function is the same as declaring it at the top of the function. Therefore, a popular style is to have all variables declared at the top of a function instead of scattered throughout. In short, you end up writing code similar to the manner in which the JavaScript engine will interpret it.

My recommendation is to have your local variables defined as the first statements in a function. This approach is recommended in Crockford’s Code Conventions, the SproutCore Style Guide, and the Dojo Style Guide:

function doSomethingWithItems(items) {

var i, len;
var value = 10;
var result = value + 10;

for (i=0, len=items.length; i < len; i++) {
doSomething(items[i]);
}
}Crockford goes on to recommend the use of a single var statement at the top of functions:

function doSomethingWithItems(items) {

var i, len,
value = 10,
result = value + 10;

for (i=0, len=items.length; i < len; i++) {
doSomething(items[i]);
}
}The Dojo Style Guide allows combining var statements only when the variables are related to one another.

My personal preference is to combine all var statements with one initialized variable per line. The equals signs should be aligned. For variables that aren’t initialized, they should appear last, as in the following example:

function doSomethingWithItems(items) {

var value = 10,
result = value + 10,
i,
len;

for (i=0, len=items.length; i < len; i++) {
doSomething(items[i]);
}
}At a minimum, I recommend combining var statements, as doing so makes your code smaller and therefore faster to download.
functional statements
JavaScript functions always be declared before being used. This design appears in Crockford’s Code Conventions. Crockford also recommends that local functions be placed immediately after variable declarations within a containing function, as in:

function doSomethingWithItems(items) {

var i, len,
value = 10,
result = value + 10;

function doSomething(item) {
// do something
}

for (i=0, len=items.length; i < len; i++) {
doSomething(items[i]);
}
}Both JSLint and JSHint will warn when a function is used before it is declared.

Additionally, function declarations should never appear inside of block statements. For example, this code won’t behave as expected:

// Bad
if (condition) {
function doSomething() {
alert("Hi!");
}
} else {
function doSomething() {
alert("Yo!");
}
}Exactly how this will work from browser to browser will vary. Most browsers automatically take the second declaration without evaluating condition; Firefox evaluates condition and uses the appropriate function declaration. This is a gray area in the ECMAScript specification and should thus be avoided. Function declarations should be used only outside of conditional statements. This pattern is explicitly forbidden in the Google JavaScript Style Guide.
Immediate Function Invocation
Immediate Function Invocation
JavaScript allows you to declare anonymous functions—functions without proper names—and assign those functions to variables or properties. For example:

var doSomething = function() {
// function body
};Such anonymous functions can also be immediately invoked to return a value to the variable by including parentheses at the very end:

// Bad
var value = function() {

// function body

return {
message: "Hi"
}
}();In the previous example, value ends up being assigned an object, because the function is immediately invoked. The problem with this pattern is that it looks very similar to assigning an anonymous function to a variable. You don’t know that this isn’t the case until you get to the very last line and see the parentheses. This sort of confusion hinders the readability of your code.

To make it obvious that immediate function invocation is taking place, put parentheses around the function, as in this example:

// Good
var value = (function() {

// function body

return {
message: "Hi"
}
}());This code now has a signal on the first line, the open paren, that the function is immediately invoked. Adding the parentheses doesn’t change the behavior of the code at all. Crockford’s Code Conventions recommends this pattern, and JSLint will warn when the parentheses are missing.
use strict
Strict Mode
ECMAScript 5 introduced strict mode, a way to alter how JavaScript is executed and parsed in the hopes of reducing errors. To put a script into strict mode, use the following pragma:

"use strict";Although this looks like a string that isn’t assigned to a variable, ECMAScript 5 JavaScript engines treat this as a command to switch into strict mode. This pragma is valid both globally as well as locally, inside of a single function. However, it’s a common recommendation (though undocumented in any popular style guide) to avoid placing "use strict" in the global scope. The reason is that strict mode applies to all code in a single file, so if you’re concatenating 11 files and one of them has global strict mode enabled, all of the files are placed into strict mode. Because strict mode operates under slightly different rules than nonstrict mode, there’s a high likelihood of errors within the other files. For this reason, it’s best to avoid placing "use strict" in the global scope. Here are some examples:

// Bad - global strict mode
"use strict";

function doSomething() {
// code
}

// Good
function doSomething() {
"use strict";

// code
}If you want strict mode to apply to multiple functions without needing to write "use strict" multiple times, use immediate function invocation:

// Good
(function() {
"use strict";

function doSomething() {
// code
}

function doSomethingElse() {
// code
}

})();In this example, doSomething() and doSomethingElse() both run in strict mode, because they are contained in an immediately invoked function with "use strict" specified.

Both JSLint and JSHint warn when "use strict" is found outside of a function. Both also expect all functions to have "use strict" specified by default; this can be turned off in both tools. I recommend using strict mode wherever possible to limit common mistakes.
=== !===
=== and !== all the time without exception
add class to elemenr
Then, in JavaScript, add the class to the element in question:

// Good - Native
element.className += " reveal";

// Good - HTML5
element.classList.add("reveal");

// Good - YUI
Y.one(element).addClass("reveal");

// Good - jQuery
$(element).addClass("reveal");

// Good - Dojo
dojo.addClass(element, "reveal");
Accidental Globals
One of the more insidious parts of JavaScript is its capacity for creating globals accidentally. When you assign a value to variable that has not previously been defined in a var statement, JavaScript automatically creates a global variable. For example:

function doSomething() {
var count = 10;
title = "Maintainable JavaScript"; // Bad: global

}
Namespaces
Namespaces
It is possible to start polluting your one global as well. Most projects that use the one-global approach also have the concept of namespacing. A namespace is simply a logical grouping of functionality under a single property on the global. For instance, YUI is set up almost exclusively using namespaces. Everything under Y.DOM is a method related to DOM manipulation, everything under Y.Event has to do with events, and so on.

Grouping functionality into namespaces brings some order to your one global object and allows team members to understand where new functionality belongs as well as where to look for existing functionality. When I worked at Yahoo!, there was an unspoken convention that each site would add its own namespace to a Y object for all of its functionality, so My Yahoo! used Y.My, Mail used Y.Mail, and so on. That design allowed teams to use one another’s code without fear of naming collisions.

You can easily create your own namespaces in JavaScript with objects, as in:

var ZakasBooks = {};

// namespace for this book
ZakasBooks.MaintainableJavaScript = {};

// namespace for another book
ZakasBooks.HighPerformanceJavaScript = {}A common convention is for each file to declare its own namespace by creating a new object on the global. In such circumstances, the previous example pattern works fine.

There are also times when each file is simply adding to a namespace; in that case, you may want a little more assurance that the namespace already exists. That’s when a global that handles namespaces nondestructively is useful. The basic pattern to accomplish this is:

var YourGlobal = {
namespace: function(ns) {
var parts = ns.split("."),
object = this,
i, len;

for (i=0, len=parts.length; i < len; i++) {
if (!object[parts[i]]) {
object[parts[i]] = {};
}
object = object[parts[i]];
}

return object;
}
};The variable YourGlobal can actually have any name. The important part is the namespace() method, which nondestructively creates namespaces based on the string that is passed in and returns a reference to the namespace object. Basic usage:

/*
* Creates both YourGlobal.Books and YourGlobal.Books.MaintainableJavaScript.
* Neither exists before hand, so each is created from scratch.
*/
YourGlobal.namespace("Books.MaintainableJavaScript");

// you can now start using the namespace
YourGlobal.Books.MaintainableJavaScript.author = "Nicholas C. Zakas";

/*
* Leaves YourGlobal.Books alone and adds HighPerformanceJavaScript to it.
* This leaves YourGlobal.Books.MaintainableJavaScript intact.
*/
YourGlobal.namespace("Books.HighPerformanceJavaScript");

// still a valid reference
console.log(YourGlobal.Books.MaintainableJavaScript.author);

// You can also start adding new properties right off the method call
YourGlobal.namespace("Books").ANewBook = {};Using a namespace() method on your one global allows developers the freedom to assume that the namespace exists. That way, each file can call namespace() first to declare the namespace the developers are using, knowing that they won’t destroy the namespace if it already exists. This approach also frees developers from the tedious task of checking to see whether the namespace exists before using it.

Note
As with other parts of your code, be sure to define some conventions around namespaces. Should they begin with uppercase letters as in YUI? Or be all lowercase as in Dojo? This is a question of preference, but defining these choices up front allows the team to use the one-global approach more effectively
event handle
Separate Application Logic
The previous example’s first problem is that the event handler contains application logic. Application logic is functionality that is related to the application rather than related to the user’s action. In the previous example, the application logic is displaying a pop up in a particular location. Even though this action should happen when the user clicks on a particular element, this may not always be the case.

It’s always best to split application logic from any event handler, because the same logic may need to be triggered by different actions in the future. For example, you may decide later that the pop up should be displayed when the user moves the cursor over the element, or when a particular key is pressed on the keyboard. Then you may end up accidentally duplicating the code into a second or third event handler attaching the same event handler to handle multiple events.

Another downside to keeping application logic in the event handler is for testing. Tests need to trigger functionality directly without going through the overhead of actually having someone click an element to get a reaction. By having application logic inside of event handlers, the only way to test is by causing the event to fire. That’s usually not the best way to test, even though some testing frameworks are capable of simulating events. It would be better to trigger the functionality with a simple function call.

You should always separate application logic from event-handling code. The first step in refactoring the previous example is to move the pop up–handling code into its own function, which will likely be on the one global object you’ve defined for your application. The event handler should also be on the same global object, so you end up with two methods:

// Better - separate application logic
var MyApplication = {

handleClick: function(event) {
this.showPopup(event);
},

showPopup: function(event) {
var popup = document.getElementById("popup");
popup.style.left = event.clientX + "px";
popup.style.top = event.clientY + "px";
popup.className = "reveal";
}

};

addListener(element, "click", function(event) {
MyApplication.handleClick(event);
});The MyApplication.showPopup() method now contains all of the application logic previously contained in the event handler. The MyApplication.handleClick() method now does nothing but call MyApplication.showPopup(). With the application logic separated out, it’s easier to trigger the same functionality from multiple points within the application without relying on specific events to fire. But this is just the first step in unraveling this event-handling code.

Email This Page (Key: e)Email This PagePrintPrintHtml View (Key: h)Html ViewZoom Out (Key: -)Zoom OutZoom In (Key: +)Zoom InToggle to Full Screen (Key: f)Previous (Key: p)PreviousNext (Key: n)NextAdvanced Search
Don’t Pass the Event Object Around
Rule #2: Don’t Pass the Event Object Around
After splitting out application logic, the next problem with the previous example is that the event object is passed around. It’s passed from the anonymous event handler to MyApplication.handleClick(), then to MyApplication.showPopup(). As mentioned previously, the event object has potentially dozens of additional pieces of information about the event, and this code only uses two of them.

Application logic should never rely on the event object to function properly for the following reasons:

■The method interface makes it unclear what pieces of data are actually necessary. Good APIs are transparent in their expectations and dependencies; passing the event object as an argument doesn’t give you any idea what it’s doing with which pieces of data.

■Because of that, you need to recreate an event object in order to test the method. Therefore, you’ll need to know exactly what the method is using to write a proper stub for testing.

These issues are both undesirable in a large-scale web application. Lack of clarity is what leads to bugs.

The best approach is to let the event handler use the event object to handle the event and then hand off any required data to the application logic. For example, the MyApplication.showPopup() method requires only two pieces of data: an x-coordinate and a y-coordinate. The method should then be rewritten to accept those as arguments:

// Good
var MyApplication = {

handleClick: function(event) {
this.showPopup(event.clientX, event.clientY);
},

showPopup: function(x, y) {
var popup = document.getElementById("popup");
popup.style.left = x + "px";
popup.style.top = y + "px";
popup.className = "reveal";
}

};

addListener(element, "click", function(event) {
MyApplication.handleClick(event); // this is okay
});In this rewritten code, MyApplication.handleClick() now passes in the x-coordinate and y-coordinate to MyApplication.showPopup() instead of passing the entire event object. It’s very clear what MyApplication.showPopup() expects to be passed in, and it’s quite easy to call that logic directly from a test or elsewhere in the code, such as:

// Great victory!
MyApplication.showPopup(10, 10);When handling events, it is best to let the event handler be the only function that touches the event object. The event handler should do everything necessary using the event object before delegating to some application logic. Thus actions such as preventing the default action or stopping event bubbling should be done strictly in the event handler, as in:

// Good
var MyApplication = {

handleClick: function(event) {

// assume DOM Level 2 events support
event.preventDefault();
event.stopPropagation();

// pass to application logic
this.showPopup(event.clientX, event.clientY);
},

showPopup: function(x, y) {
var popup = document.getElementById("popup");
popup.style.left = x + "px";
popup.style.top = y + "px";
popup.className = "reveal";
}

};

addListener(element, "click", function(event) {
MyApplication.handleClick(event); // this is okay
});In this code, MyApplication.handleClick() is the defined event handler, so it makes the calls to event.preventDefault() and event.stopPropagation() before passing data to the application logic, which is exactly how the relationship between event handlers and the application should work. Because the application logic no longer depends on event, it’s easy to use that same logic in multiple places as well as to write tests.
Avoid Null Comparisons > Detecting Primitive Values
Detecting Primitive Values
There are five primitive types in JavaScript: string, number, boolean, null, and undefined. If you are expecting a value to be a string, number, boolean, or undefined, then the typeof operator is your best option. The typeof operator works on a variable and returns a string indicating the type of value:

■For strings, typeof returns “string.”

■For numbers, typeof returns “number.”

■For booleans, typeof returns “boolean.”

■For undefined, typeof returns “undefined.”

Basic syntax for typeof is as follows:

typeof variableYou may also see typeof used in this manner:

typeof(variable)Although this is valid JavaScript syntax, this pattern makes typeof appear to be a function instead of an operator. For this reason, the pattern without parentheses is recommended.

Using typeof for detecting these four primitive value types is the safest way to code defensively. Here are some examples:

// detect a string
if (typeof name === "string") {
anotherName = name.substring(3);
}

// detect a number
if (typeof count === "number") {
updateCount(count);
}

// detect a boolean
if (typeof found === "boolean" && found) {
message("Found!");
}

// detect undefined
if (typeof MyApp === "undefined") {
MyApp = {
// code
};
}The typeof operator is also unique in that it can be used on an undeclared variable without throwing an error. Both undeclared variables and variables whose value is undefined return “undefined” when typeof is used.

The last primitive type, null, is the one that you normally shouldn’t be testing for. As stated earlier, comparing simply against null generally doesn’t give you enough information about whether the value is expected. There is one exception: if one of the expected values is actually null, then it is okay to test for null directly. The comparison should be done using either === or !== against null. For example:

// If you must test for null, this is the way to do it
var element = document.getElementById("my-div");
if (element !== null) {
element.className = "found";
}It is entirely possible for document.getElementById() to return null if the given DOM element isn’t found. The method will return either null or an element. Because null is one of the expected outcomes, it’s okay to test for it using !==.

Note
Running typeof null returns “object,” making this an inefficient way to test for null values. If you must test for null, use the identically equal operator (===) or the not identically equal (!==) operator.
Detecting Reference Values
Detecting Reference Values
Reference values are also known as objects. In JavaScript, any value that isn’t a primitive is definitely a reference. There are several built-in reference types such as Object, Array, Date, and Error, just to name a few. The typeof operator is of little use for reference values, because it returns “object” for any type of object:

console.log(typeof {}); // "object"
console.log(typeof []); // "object"
console.log(typeof new Date()); // "object"
console.log(typeof new RegExp()); // "object"Another downside to using typeof for objects is that typeof returns “object” for null values as well:

console.log(typeof null); // "object"This quirk, which has been recognized as a serious bug in the specification, prevents accurate detection of null using typeof.

The instanceof operator is the best way to detect values of a particular reference type. Basic syntax for instanceof is:

value instanceof constructorHere are some examples:

// detect a Date
if (value instanceof Date) {
console.log(value.getFullYear());
}

// detect a RegExp
if (value instanceof RegExp) {
if (value.test(anotherValue)) {
console.log("Matches");
}
}

// detect an Error
if (value instanceof Error) {
throw value;
}An interesting feature of instanceof is that it not only checks the constructor used to create the object but also checks the prototype chain. The prototype chain contains information about the inheritance pattern used to define the object. For instance, every object inherits from Object by default, so every object returns true for value instanceof Object. For example:

var now = new Date();

console.log(now instanceof Object); // true
console.log(now instanceof Date); // trueDue to this behavior, it’s typically not good enough to use value instanceof Object when you’re expecting a particular type of object.

The instanceof operator also works with custom types that you’ve defined for yourself. For instance:

function Person(name) {
this.name = name;
}

var me = new Person("Nicholas");

console.log(me instanceof Object); // true
console.log(me instanceof Person); // trueThis example creates a custom Person type. The me variable is an instance of Person, so me instanceof Person is true. As mentioned previously, all objects are also considered instances of Object, so me instanceof Object is also true.

The instanceof operator is the only good way to detect custom types in JavaScript. It’s also good to use for almost all built-in JavaScript types. There is, however, one serious limitation.

Suppose that an object from one browser frame (frame A) is passed into another (frame B). Both frames have the constructor function Person defined. If the object from frame A is an instance of Person in frame A, then the following rules apply:

// true
frameAPersonInstance instanceof frameAPerson

// false
frameAPersonInstance instanceof frameBPersonBecause each frame has its own copy of Person, it is considered an instance of only that frame’s copy of Person, even though the two definitions may be identical.

This issue is a problem not just for custom types but also for two very important built-in types: functions and arrays. For these two types, you don’t want to use instanceof at all.
Detecting Properties
Another time when when developers typically use null (and also undefined) is when trying to determine whether a property is present in an object. For example:

// Bad: Checking falsyness
if (object[propertyName]) {
// do something
}

// Bad: Compare against null
if (object[propertyName] != null) {
// do something
}

// Bad: Compare against undefined
if (object[propertyName] != undefined) {
// do something
}Each of these examples is actually checking the value of the property with the given name rather than the existence of the property with the given name, which can result in errors when you’re dealing with falsy values such as 0, "" (empty string), false, null, and undefined. After all, these are all valid values for properties. For example, if the property is keeping track of a number, the value might very well be zero. In that case, the first example will likely cause a bug. Likewise, if the property value could be null or undefined, all three examples can cause bugs.

The best way to detect the presence of a property is to use the in operator. The in operator simply checks for the presence of the named property without reading its value, avoiding ambiguity with statements such as those earlier in this section. If the property either exists on the instance or is inherited from the object’s prototype, the in operator returns true. For example:

var object = {
count: 0,
related: null
};

// Good
if ("count" in object) {
// this executes
}

// Bad: Checking falsy values
if (object["count"]) {
// this doesn't execute
}

// Good
if ("related" in object) {
// this executes
}

// Bad: Checking against null
if (object["related"] != null) {
// doesn't execute
}If you only want to check for the existence of the property on the object instance, then use the hasOwnProperty() method. All JavaScript objects that inherit from Object have this method, which returns true when the property exists on the instance (if the property only exists on the prototype, in which case it returns false). Keep in mind that DOM objects in Internet Explorer 8 and earlier do not inherit from Object and therefore do not have this property. That means you’ll need to check for the existence of hasOwnProperty() before using it on potential DOM objects (if you know the object isn’t from the DOM, you can omit this step).


// Good for all non-DOM objects
if (object.hasOwnProperty("related")) {
//this executes
}

// Good when you're not sure
if ("hasOwnProperty" in object && object.hasOwnProperty("related")) {
//this executes
}Because of Internet Explorer 8 and earlier, I tend to use the in operator whenever possible and only use hasOwnProperty() when I need to be sure of an instance property.

Whenever you want to check for the existence of the property, make sure to use the in operator or hasOwnProperty(). Doing so can avoid a lot of bugs.

Note
Of course, if you want to specifically check for the values of null or undefined, use the guidelines in Chapter 1.
What Is Configuration Data?
Configuration data is any hardcoded value in an application. Consider the following example:

// Configuration data embedded in code
function validate(value) {
if (!value) {
alert("Invalid value");
location.href = "/errors/invalid.php";
}
}

function toggleSelected(element) {
if (hasClass(element, "selected")) {
removeClass(element, "selected");
} else {
addClass(element, "selected");
}
}There are three pieces of configuration data in this code. The first is the string “Invalid value,” which is displayed to the user. As a UI string, there’s a good chance that it will change frequently. The second is the URL /errors/invalid.php. URLs tend to change as development progresses, due to architectural decisions. The third is the CSS class name “selected.” This class name is used three times, meaning that a class name change requires changes in three different places, increasing the likelihood that one will be missed.

These are all considered configuration data, because they are hardcoded values that may change in the future. The following are all examples of configuration data:

■URLs

■Strings that are displayed in the UI

■Repeated unique values

■Settings (i.e., items per page)

■Any value that may change

The key point to remember about configuration data is that it changes, and you don’t want to be modifying your JavaScript source code because someone changed his mind about a message to display on the home page.
Externalizing Configuration Data
The first step in separating configuration data from code is to externalize the configuration data, which means getting the data out of the middle of your JavaScript code. Here’s the previous example with the configuration data externalized:

// Configuration data externalized
var config = {
MSG_INVALID_VALUE: "Invalid value",
URL_INVALID: "/errors/invalid.php",
CSS_SELECTED: "selected"
};

function validate(value) {
if (!value) {
alert(config.MSG_INVALID_VALUE);
location.href = config.URL_INVALID;
}
}

function toggleSelected(element) {
if (hasClass(element, config.CSS_SELECTED)) {
removeClass(element, config.CSS_SELECTED);
} else {
addClass(element, config.CSS_SELECTED);
}
}This example stores all of the configuration data in the config object. Each property of config holds a single piece of data, and each property name has a prefix indicating the type of data (MSG for a UI message, URL for a URL, and CSS for a class name). The naming convention is, of course, a matter of preference. The important part of this code is that all of the configuration data has been removed from the functions and replaced with placeholders from the config object.

Externalizing the configuration data means that anyone can go in and make a change without introducing an error in the application logic. It also means that the entire config object can be moved into its own file, so edits are made far away from the code that uses the data.
Storing Configuration Data
Storing Configuration Data
Configuration data is best stored in a separate file to create a clean separation between it and application logic. A good starting point is to have a separate JavaScript file for configuration data. Once the configuration data is in a separate file, it opens up more possibilities for managing that data. A worthwhile option is moving your configuration data into a non-JavaScript file.

Even though you’re writing a JavaScript application, JavaScript isn’t a great way to store configuration data. That’s because the syntax is still that of a programming language, so you need to be sure you haven't introduced syntax errors. If you end up concatenating JavaScript files together, a syntax error in a single line breaks the overall application. Configuration data truly belong in files that are hard to format incorrectly, and once you have that file, it is trivial to convert the configuration data into a JavaScript format automatically.

One of my favorite formats for configuration data is a Java properties file. Java properties files are simple name-value pairs in which each pair takes a single line (unless you put in a multiple-line sequence) in the form name=value. It doesn’t matter if there are spaces around the equals sign, so even that syntax isn’t hard to get right. Comments are indicated by preceding the line with a # character. Here’s an example:

# UI Strings
MSG_INVALID_VALUE = Invalid value

# URLs
URL_INVALID = /errors/invalid.php

# CSS Classes
CSS_SELECTED = selectedThis properties file contains the same properties as the config object from the previous example. Notice how much simpler the file layout is. There are no quoted strings, which means that you don’t have to worry about proper escaping or forgetting to close a string. There are also no semicolons or commas to worry about. You can simply put in your data and not worry about JavaScript syntax at all.

The next step is to convert this file into something that’s usable by JavaScript. There are generally three formats in which you want your configuration data. The first is JSON, which is useful when embedding your data into another file or setting up data for retrieval from the server. For instance:

{"MSG_INVALID_VALUE":"Invalid value","URL_INVALID":"/errors/invalid.php",
"CSS_SELECTED":"selected"}The second is JSONP (JSON with padding), which returns the JSON structure wrapped in a function:

myfunc({"MSG_INVALID_VALUE":"Invalid value","URL_INVALID":"/errors/invalid.php",
"CSS_SELECTED":"selected"});Because JSONP is valid JavaScript, you can concatenate this code into other files to give them access to the data.

The last option is plain JavaScript, in which you assign the JSON object to a variable to use later, as in:

var config={"MSG_INVALID_VALUE":"Invalid value","URL_INVALID":"/errors/invalid.php",
"CSS_SELECTED":"selected"};As with JSONP, the plain JavaScript version can be combined with other JavaScript files easily once produced.

For these common use cases, I have created a tool called Props2Js that reads Java properties files and outputs the data into one of these three formats. Props2Js is free and open source, available at https://github.com/nzakas/props2js/. It works like this:

java -jar props2js-0.1.0.jar --to jsonp --name myfunc
--output result.js source.propertiesThe --to option specifies the output format, either “js,” “json,” or “jsonp.” The --name option specifies either the variable name (for “js”) or the function name (for “jsonp”); this option is ignored for “json.” The --output option specifies the file to write the data into. So this line takes the Java properties file named source.properties and outputs JSONP with a callback function of myfunc to a file named result.js.

Using a tool like Props2Js allows you to keep configuration data in a simpler file format and then easily convert your configuration data into a format that is usable by JavaScript later.
What Do You Own?
You own an object when your code creates the object. The code that creates the object may not have necessarily been written by you, but as long as it’s the code you’re responsible for maintaining, then you own that object. For instance, the YUI team owns the YUI object, and the Dojo team owns the dojo object. Even though the original person who wrote the code defining the object may not work on it anymore, the respective teams are still the owners of those objects.

When you use a JavaScript library in a project, you don’t automatically become the owner of its objects. In a multiple-developer project, everyone is assuming that the library objects work as they are documented. If you’re using YUI and make modifications to the YUI object, then you’re setting up a trap for your team. Someone is going to fall in, and it’s going to cause a problem.

Remember, if your code didn’t create the object, then it’s not yours to modify, which includes:

■Native objects (Object, Array, and so on)

■DOM objects (for example, document)

■Browser Object Model (BOM) objects (such as window)

■Library objects

All of these objects are part of your project’s execution environment. You can use these pieces as they are already provided to you or create new functionality; you should not modify what’s already there.
Rules
The Rules
Enterprise software needs a consistent and dependable execution environment to be maintainable. In other languages, you consider existing objects as libraries for you to use to complete your task. In JavaScript, you might see existing objects as a playground in which you can do anything you want. You should treat the existing JavaScript objects as you would a library of utilities:

■Don’t override methods.

■Don’t add new methods.

■Don’t remove existing methods.

When you’re the only one working on a project, it’s easy to get away with these types of modification because you know them and expect them. When working with a team on a large project, making changes like this causes mass confusion and a lot of lost time.
two forms of inheritance
There are two basic forms of inheritance in JavaScript: object-based and type-based.

Note
There are still some significant inheritance limitations in JavaScript. First, inheriting from DOM or BOM objects doesn’t work (yet). Second, inheriting from Array doesn’t quite work due to the intricacies of how numeric indices relate to the length property.
Object-Based Inheritance
Object-Based Inheritance
In object-based inheritance, frequently called prototypal inheritance, one object inherits from another without invoking a constructor function. The ECMAScript 5 Object.create() method is the easiest way for one object to inherit from another. For instance:
var person = {
name: "Nicholas",
sayName: function() {
alert(this.name);
}
};

var myPerson = Object.create(person);

myPerson.sayName(); // pops up "Nicholas"This example creates a new object myPerson that inherits from person. The inheritance occurs as myPerson’s prototype is set to person. After that, myPerson is able to access the same properties and methods on person until new properties or methods with the same name are defined. For instance, defining myPerson.sayName() automatically cuts off access to person.sayName():

myPerson.sayName = function() {
alert("Anonymous");
};

myPerson.sayName(); // pops up "Anonymous"
person.sayName(); // pops up "Nicholas"The Object.create() method allows you to specify a second argument, which is an object containing additional properties and methods to add to the new object. For example:

var myPerson = Object.create(person, {
name: {
value: "Greg"
}
});

myPerson.sayName(); // pops up "Greg"
person.sayName(); // pops up "Nicholas"In this example, myPerson is created with its own value for name, so calling sayName() displays “Greg” instead of “Nicholas.”

Once a new object is created in this manner, you are completely free to modify the new object in whatever manner you see fit. After all, you are the owner of the new object, so you are free to add new methods, override existing methods, and even remove methods (or rather just prevent access to them) on your new object.
Type-Based Inheritance
Type-based inheritance works in a similar manner to object-based inheritance, in that it relies on the prototype to inherit from an existing object. However, type-based inheritance works with constructor functions instead of objects, which means you need access to the constructor function of the object you want to inherit from. You saw an example of type-based inheritance earlier in this book:

function MyError(message) {
this.message = message;
}

MyError.prototype = new Error();In this example, the MyError type inherits from Error, which is called the super type. It does so by assigning a new instance of Error to MyError.prototype. After that, every instance of MyError inherits its properties and methods from Error as well as now working with instanceof:

var error = new MyError("Something bad happened.");

console.log(error instanceof Error); // true
console.log(error instanceof MyError); // trueType-based inheritance is best used with developer-defined constructor functions rather than those found natively in JavaScript. Also, type-based inheritance typically requires two steps: prototypal inheritance and then constructor inheritance. Constructor inheritance is when the super type constructor is called with a this-value of the newly created object. For example:

function Person(name) {
this.name;
}

function Author(name) {
Person.call(this, name); // inherit constructor
}

Author.prototype = new Person();In this code, the Author type inherits from Person. The property name is actually managed by the Person type, so Person.call(this, name) allows the Person constructor to continue defining that property. The Person constructor runs on this, which is the new Author object. So name ends up being defined on the new Author object.

As with object-based inheritance, type-based inheritance allows you flexibility in how you create new objects. Defining a type allows you to have multiple instances of the same object, all of which inherit from a common super type. Your new type should define exactly the properties and methods you want to use, and those can be completely different from the super type.
Type-Based Inheritance
Type-based inheritance works in a similar manner to object-based inheritance, in that it relies on the prototype to inherit from an existing object. However, type-based inheritance works with constructor functions instead of objects, which means you need access to the constructor function of the object you want to inherit from. You saw an example of type-based inheritance earlier in this book:

function MyError(message) {
this.message = message;
}

MyError.prototype = new Error();In this example, the MyError type inherits from Error, which is called the super type. It does so by assigning a new instance of Error to MyError.prototype. After that, every instance of MyError inherits its properties and methods from Error as well as now working with instanceof:

var error = new MyError("Something bad happened.");

console.log(error instanceof Error); // true
console.log(error instanceof MyError); // trueType-based inheritance is best used with developer-defined constructor functions rather than those found natively in JavaScript. Also, type-based inheritance typically requires two steps: prototypal inheritance and then constructor inheritance. Constructor inheritance is when the super type constructor is called with a this-value of the newly created object. For example:

function Person(name) {
this.name;
}

function Author(name) {
Person.call(this, name); // inherit constructor
}

Author.prototype = new Person();In this code, the Author type inherits from Person. The property name is actually managed by the Person type, so Person.call(this, name) allows the Person constructor to continue defining that property. The Person constructor runs on this, which is the new Author object. So name ends up being defined on the new Author object.

As with object-based inheritance, type-based inheritance allows you flexibility in how you create new objects. Defining a type allows you to have multiple instances of the same object, all of which inherit from a common super type. Your new type should define exactly the properties and methods you want to use, and those can be completely different from the super type.
Indentation
Indentation
Each indentation level is made up of four spaces. Do not use tabs.

// Good
if (true) {
doSomething();
}
Line Length
Line Length
Each line should be no longer than 80 characters. If a line goes longer than 80 characters, it should be wrapped after an operator (comma, plus, etc.). The following line should be indented two levels (eight characters).

// Good
doSomething(argument1, argument2, argument3, argument4,
argument5);

// Bad: Following line only indented four spaces
doSomething(argument1, argument2, argument3, argument4,
argument5);

// Bad: Breaking before operator
doSomething(argument1, argument2, argument3, argument4
, argument5);
Primitive Literals
Primitive Literals
Strings should always use double quotes (never single quotes) and should always appear on a single line. Never use a slash to create a new line in a string.
Operator Spacing
Operators with two operands must be preceded and followed by a single space to make the expression clear. Operators include assignments and logical operators.

// Good
var found = (values[i] === item);

// Good
if (found && (count > 10)) {
doSomething();
}
Parentheses Spacing
// Good
var found = (values[i] === item);

// Good
if (found && (count > 10)) {
doSomething();
}
Object Literals
Object literals should have the following format:

■The opening brace should be on the same line as the containing statement.

■Each property-value pair should be indented one level with the first property appearing on the next line after the opening brace.

■Each property-value pair should have an unquoted property name, followed by a colon (no space preceding it), followed by the value.

■If the value is a function, it should wrap under the property name and should have a blank line both before and after the function.

■Additional empty lines may be inserted to group related properties or otherwise improve readability.

■The closing brace should be on a separate line.

Examples:

// Good
var object = {

key1: value1,
key2: value2,

func: function() {
// do something
},

key3: value3
};

// Bad: Improper indentation
var object = {
key1: value1,
key2: value2
};

// Bad: Missing blank lines around function
var object = {

key1: value1,
key2: value2,
func: function() {
// do something
},
key3: value3
};When an object literal is passed to a function, the opening brace should be on the same line as if the value is a variable. All other formatting rules listed earlier still apply.

// Good
doSomething({
key1: value1,
key2: value2
});

// Bad: All on one line
doSomething({ key1: value1, key2: value2 });
Single-Line Comments
Single-line comments should be used to documentation one line of code or a group of related lines of code. A single-line comment may be used in three ways:

■On a separate line, describing the code beneath it

■At the end of a line, describing the code before it

■On multiple lines, to comment out sections of code

When on a separate line, a single-line comment should be at the same indentation level as the code it describes and be preceded by a single line. Never use multiple single-line comments on consecutive lines; use a multiline comment instead.

// Good
if (condition){

// if you made it here, then all security checks passed
allowed();
}

// Bad: No empty line preceding comment
if (condition){
// if you made it here, then all security checks passed
allowed();
}
Multiline Comments
Multiline comments should be used to document code that requires more explanation. Each multiline comment should have at least three lines:

1.The first line contains only the /* comment opening. No further text is allowed on this line.

2.The next line or lines have a * aligned with the * in the first line. Text is allowed on these lines.

3.The last line has the */ comment opening aligned with the preceding lines. No other text is allowed on this line.

The first line of multiline comments should be indented to the same level as the code it describes. Each subsequent line should have the same indentation plus one space (for proper alignment of the * characters). Each multiline comment should be preceded by one empty line.

// Good
if (condition){

/*
* if you made it here,
* then all security checks passed
*/
allowed();
}
Comment Annotations
Comments may be used to annotate pieces of code with additional information. These annotations take the form of a single word followed by a colon. The acceptable annotations are:

TODO
Indicates that the code is not yet complete. Information about the next steps should be included.

HACK
Indicates that the code is using a shortcut. Information about why the hack is being used should be included. This may also indicate that it would be nice to come up with a better way to solve the problem.

XXX
Indicates that the code is problematic and should be fixed as soon as possible.

FIXME
Indicates that the code is problematic and should be fixed soon. Less important than XXX.

REVIEW
indicates that the code needs to be reviewed for potential changes.

These annotations may be used with either single-line or multiline comments and should follow the same formatting rules as the general comment type.

Examples:

// Good
// TODO: I'd like to find a way to make this faster
doSomething();

// Good
/*
* HACK: Have to do this for IE. I plan on revisiting in
* the future when I have more time. This probably should
* get replaced before v1.2.
*/
Variable Declarations
All variables should be declared before they are used. Variable declarations should take place at the beginning of a function using a single var statement with one variable per line. All lines after the first should be indented one level so that the variable names line up. Variables should be initialized when declared if applicable, and the equals operator should be at a consistent indentation level. Initialized variables should come first followed by uninitialized variables.

// Good
var count = 10,
name = "Nicholas",
found = false,
empty;

// Bad: Improper initialization alignment
var count = 10,
name = "Nicholas",
found= false,
empty;

// Bad: Incorrect indentation
var count = 10,
name = "Nicholas",
found = false,
empty;

// Bad: Multiple declarations on one line
var count = 10, name = "Nicholas",
found = false, empty;

// Bad: Uninitialized variables first
var empty,
count = 10,
name = "Nicholas",
found = false;

// Bad: Multiple var statements
var count = 10,
name = "Nicholas";

var found = false,
empty;Always declare variables. Implied globals should not be used.
Function Declarations
Functions should be declared before they are used. When a function is not a method (that is, not attached to an object), it should be defined using the function declaration format (not function expression format or using the Function constructor). There should be no space between the function name and the opening parenthesis. There should be one space between the closing parenthesis and the right brace. The right brace should be on the same line as the function keyword. There should be no space after the opening parenthesis or before the closing parenthesis. Named arguments should have a space after the comma but not before it. The function body should be indented one level.

// Good
function doSomething(arg1, arg2) {
return arg1 + arg2;
}

// Bad: Improper spacing of first line
function doSomething (arg1, arg2){
return arg1 + arg2;
}

// Bad: Function expression
var doSomething = function(arg1, arg2) {
return arg1 + arg2;
};

// Bad: Left brace on wrong line
function doSomething(arg1, arg2)
{
return arg1 + arg2;
}

// Bad: Using Function constructor
var doSomething = new Function("arg1", "arg2", "return arg1 + arg2");Functions declared inside of other functions should be declared immediately after the var statement.

// Good
function outer() {

var count = 10,
name = "Nicholas",
found = false,
empty;

function inner() {
// code
}

// code that uses inner()
}

// Bad: Inner function declared before variables
function outer() {

function inner() {
// code
}

var count = 10,
name = "Nicholas",
found = false,
empty;

// code that uses inner()
}Anonymous functions may be used for assignment of object methods or as arguments to other functions. There should be no space between the function keyword and the opening parenthesis.

// Good
object.method = function() {
// code
};

// Bad: Incorrect spacing
object.method = function () {
// code
};Immediately invoked functions should surround the entire function call with parentheses.

// Good
var value = (function() {

// function body

return {
message: "Hi"
}
}());

// Bad: No parentheses around function call
var value = function() {

// function body

return {
message: "Hi"
}
}();

// Bad: Improper parentheses placement
var value = (function() {

// function body

return {
message: "Hi"
}
})();
Naming
Care should be taken to name variables and functions properly. Names should be limited to alphanumeric characters and, in some cases, the underscore character. Do not use the dollar sign ($) or backslash (\) characters in any names.

Variable names should be formatted in camel case with the first letter lowercase and the first letter of each subsequent word uppercase. The first word of a variable name should be a noun (not a verb) to avoid confusion with functions. Do not use underscores in variable names.

// Good
var accountNumber = "8401-1";

// Bad: Begins with uppercase letter
var AccountNumber = "8401-1";

// Bad: Begins with verb
var getAccountNumber = "8401-1";

// Bad: Uses underscore
var account_number = "8401-1";Function names should also be formatted using camel case. The first word of a function name should be a verb (not a noun) to avoid confusion with variables. Do not use underscores in function names.

// Good
function doSomething() {
// code
}

// Bad: Begins with uppercase letter
function DoSomething() {
// code
}

// Bad: Begins with noun
function car() {
// code
}

// Bad: Uses underscores
function do_something() {
// code
}Constructor functions—functions used with the new operator to create new objects—should be formatted in camel case but must begin with an uppercase letter. Constructor function names should begin with a nonverb, because new is the action of creating an object instance.

// Good
function MyObject() {
// code
}

// Bad: Begins with lowercase letter
function myObject() {
// code
}

// Bad: Uses underscores
function My_Object() {
// code
}

// Bad: Begins with verb
function getMyObject() {
// code
}Variables that act as constants (values that won’t be changed) should be formatted using all uppercase letters with words separated by a single underscore.

// Good
var TOTAL_COUNT = 10;

// Bad: Camel case
var totalCount = 10;

// Bad: Mixed case
var total_COUNT = 10;Object properties follow the same naming conventions as variables. Object methods follow the same naming conventions as functions. If a property or method is meant to be private, then it should be prefixed with an underscore character.

// Good
var object = {
_count: 10,

_getCount: function () {
return this._count;
}
};
Strict Mode
Strict Mode
Strict mode should be used only inside of functions, never globally.

// Bad: Global strict mode
"use strict";

function doSomething() {
// code
}

// Good
function doSomething() {
"use strict";

// code
}If you want strict mode to apply to multiple functions without needing to write "use strict" multiple times, use immediate function invocation:

// Good
(function() {
"use strict";

function doSomething() {
// code
}

function doSomethingElse() {
// code
}

}());
Ternary Operator
The ternary operator should be used only for assigning values conditionally and never as a shortcut for an if statement.

// Good
var value = condition ? value1 : value2;
for Statement
The for class of statements should have the following form:

for (initialization; condition; update) {
statements
}

for (variable in object) {
statements
}Variables should not be declared in the initialization section of a for statement.

// Good
var i,
len;

for (i=0, len=10; i < len; i++) {
// code
}

// Bad: Variables declared during initialization
for (var i=0, len=10; i < len; i++) {
// code
}

// Bad: Variables declared during initialization
for (var prop in object) {
// code
}When using a for-in statement, double-check if you need to use hasOwnProperty