日期:2014-05-16  浏览次数:20322 次

JavaScript Patterns 读书笔记(一)

一.Global

  • 全局域中的this = window.
    myglobal = "hello"; // antipattern
    console.log(myglobal); // "hello"
    console.log(window.myglobal); // "hello"
    console.log(window["myglobal"]); // "hello"
    console.log(this.myglobal); // "hello", 全局域中的this = window.
    ??
  • Another antipattern that creates implied globals is to chain assignments??as part of a var declaration. In the following snippet, a is local but b??becomes global, which is probably not what you meant to do:
    // antipattern, do not use
    function foo() {
    	var a = b = 0;
    	// ...
    }
    
    ?
    ??? If you’re wondering why that happens, it’s because of the right-to-left evaluation.??First,the expression b = 0 is evaluated and in this case b is not declared. The return?value of this expression is 0, and it’s assigned to?the new local variable declared with var a.?In other words, it’s as if you’ve typed:
    ??
    var a = (b = 0);
    ?
    ?If you’ve already declared the variables, chaining assignments is fine and??doesn’t create unexpected globals. Example:
    function foo() {
    	var a, b;
    	// ...
    	a = b = 0; // both local
    }
    ?
  • Side Effects When Forgetting var:
    ??There’s one slight difference between implied globals and explicitly defined ones—the difference?is in the ability to undefine these variables using the delete operator:

    ?????? ? Globals created with var (those created in the program outside of any function) cannot be deleted.
    ????????? Implied globals created without var (regardless if created inside functions) can?be?deleted.
    ????This shows that implied globals are technically not real variables, but they are properties of??the global object. Properties can be deleted with the delete operator whereas variables cannot:
    // define three globals
    var global_var = 1;
    global_novar = 2; // antipattern
    (function () {
    	global_fromfunc = 3; // antipattern
    }());
    // attempt to delete
    delete global_var; // false
    delete global_novar; // true
    delete global_fromfunc; // true
    // test the deletion
    typeof global_var; // "number"
    typeof global_novar; // "undefined"
    typeof global_fromfunc; // "undefined"
    
    ?? ?In ES5 strict mode, assignments to undeclared variables (such as the two antipatterns in the preceding snippet) will throw an error.
  • Hoisting: A Problem with Scattered vars
    ????JavaScript enables you to have multiple var statements anywhere in a function, and?they all act as if the variables were declared at the top of the function. This behavior is??known as hoisting. This can lead to logical errors when you use a variable and then you?declare it further in the function. For JavaScript, as long as a variable is in the same?scope (same function), it’s considered declared, even when it’s used before the var?declaration. Take a look at this example:
    // antipattern
    myname = "global"; // global variable
    function func() {
    	alert(myname); // "undefined"
    	var myname = "local";
    	alert(myname); // "local"
    }
    func();
    
    ?? ?In this example, you might expect that the first alert() will prompt “global” and the?second will prompt “local.” It’s a reasonable expectation because, at the time of the?first alert, myname was not declared and therefore the function should probably “see”?the global myname. But that’s not how it works. The first alert will say “undefined”?because myname is considered declared as a local variable to the function. (Although the?declaration comes after.) All the variable declarations get hoisted to the top of the?function. Therefore to avoid this type of confusion, it’s best to declare upfront all variables?you intend to use.?The preceding code snippet will behave as if it were implemented like so:
    myname2 = "global"; // global variable
    function func_fixed() {
    	var