-
Avoiding Implied Typecasting
JavaScript implicitly typecasts variables when you compare them. That’s why compar- isons such as false == 0 or "" == 0 return true.
To avoid confusion caused by the implied typecasting, always use the === and !== operators that check both the values and the type of the expressions you compare:
var zero = 0;
if (zero === false) {
// not executing because zero is 0, not false }
// antipattern
if (zero == false) {
// this block is executed... }
There’s another school of thought that subscribes to the opinion that it’s redundant to use === when == is sufficient. For example, when you use typeof you know it returns a string, so there’s no reason to use strict equality. However, JSLint requires strict equal- ity; it does make the code look consistent and reduces the mental effort when reading code. (“Is this == intentional or an omission?”)
Number Conversions with parseInt()
Using parseInt() you can get a numeric value from a string. The function accepts a second radix parameter, which is often omitted but shouldn’t be. The problems occur when the string to parse starts with 0: for example, a part of a date entered into a form field. Strings that start with 0 are treated as octal numbers (base 8) in ECMAScript 3; however, this has changed in ES5. To avoid inconsistency and unexpected results, al- ways specify the radix parameter:
var month = "06", year = "09";
month = parseInt(month, 10); year = parseInt(year, 10);
In this example, if you omit the radix parameter like parseInt(year), the returned value willbe0,because“09”assumesoctalnumber(asifyoudidparseInt(year, 8))and09 is not a valid digit in base 8.
Alternative ways to convert a string to a number include:
+"08" // result is 8 Number("08") // 8
These are often faster than parseInt(), because parseInt(), as the name suggests, parses and doesn’t simply convert. But if you’re expecting input such as “08 hello”, parseInt() will return a number, whereas the others will fail with NaN.
Writing API Docs
JavaScript there are two excellent tools, both free and open source: the JSDoc Toolkit (http://code.google.com/p/jsdoc-toolkit/) and YUIDoc (http://yuilibrary.com/projects/yuidoc).
-
Reducing the number of globals, ideally to one per application
-
Using a single var per function, which helps keep an eye on all variables in a single
spot and prevents surprises caused by the variable hoisting behavior
-
for loops, for-in loops, switches, “eval() is evil,” not augmenting built-in
prototypes
-
Following coding conventions (consistent white space, indentation, using curly
braces and semicolons even when they are optional) and naming conventions (for
constructors, functions, and variables)
Object Constructor Catch
You have no reason to use the new Object() constructor when you can use an object literal, but you might be inheriting legacy code written by others, so you should be aware of one “feature” of this constructor (or yet another reason not to use it). The feature in question is that the Object() constructor accepts a parameter and, depending on the value passed, it may decide to delegate the object creation to another built-in constructor and return a different object than you expect.
Following are a few examples of passing a number, a string, and a boolean value to new Object(); the result is that you get objects created with a different constructor:
-
// Warning: antipatterns ahead
// an empty object var o = new Object();
console.log(o.constructor === Object); // true
// a number object
var o = new Object(1); console.log(o.constructor === Number); // true console.log(o.toFixed(2)); // "1.00"
// a string object
var o = new Object("I am a string"); console.log(o.constructor === String); // true // normal objects don't have a substring()
// method but string objects do console.log(typeof o.substring); // "function"
// a boolean object
var o = new Object(true); console.log(o.constructor === Boolean); // true
This behavior of the Object() constructor can lead to unexpected results when the value you pass to it is dynamic and not known until runtime. Again, in conclusion, don’t use new Object(); use the simpler and reliable object literal instead.
-
// Warning: antipatterns ahead
-
Object literal notation—An elegant way to create objects as comma-delimited key- value pairs, wrapped in curly brackets.
-
Constructor functions—Built-in constructors (which almost always have a better and shorter literal notation) and custom constructors
-
Ways to make sure custom constructors always behave as if invoked with new
-
Array literal notation—Comma-delimited lists of values inside square brackets
-
JSON—A data format consisting of object and array literals
-
Regular expression literals
-
Other built-in constructors to avoid: String(), Number(), Boolean(), and the different Error() constructors
-
Reducing the number of globals, ideally to one per application
Built-in constructors (avoid)
var o = new Object();
var a = new Array();
var re = new RegExp( "[a-z]",
"g" );
var s = new String();
var n = new Number();
var b = new Boolean(); throw new Error("uh-oh");Literals and primitives (prefer)
var o = {};
var a = [];
var re = /[a-z]/g;var s = ""; var n = 0;
var b = false;throw {
name: "Error",message: "uh-oh" };
... or
throw Error("uh-oh");
전체 페이지뷰
2013년 12월 9일 월요일
javascript patterns
from javascript patterns
피드 구독하기:
댓글 (Atom)
댓글 없음:
댓글 쓰기