전체 페이지뷰

2013년 12월 9일 월요일

javascript patterns

from javascript patterns





  1. 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:
      1. // 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. 


    • 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 

  2. 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"); 

댓글 없음:

댓글 쓰기