Write high-quality JS code on

Source: Internet
Author: User
Tags variable scope javascript array

Want to write efficient JavaScript class library but do not do;

Try to read someone else's library, but understand it as well as you know it;

Want to delve into the JS advanced function, but the content of the authoritative book is too fragmented,

Even remember "usage", but to "use" when you do not think "law."

Perhaps you and I, as if there is an invisible power bound to our plan, let us repeatedly think of the limitations of knowledge, so that we step in place, difficult to leap forward.

During this time, a variety of assignments, curriculum design, experimental reports, pressure doubled. It's hard to squeeze a little bit of time, never sleep in, and sort out the books that you've seen in the past, just to get a little closer to writing your own class library.

This article is for reference from the JavaScript language pristine and effective JavaScript. Examples have been debugged, after understanding, I would like to make some of the "esoteric" reason to say a little bit more obvious.

1. Variable Scope

Scopes are like oxygen to programmers. It's everywhere, and even, you tend not to think about him. But when it is contaminated (for example, using Global objects), you will feel suffocated (for example, the application response slows down). JavaScript core scope rules are simple, well-designed, and powerful. The efficient use of JavaScript requires mastering some basic concepts of variable scope and understanding some of the extreme situations that can lead to elusive, annoying problems.

1.1 Use global variables as little as possible

JavaScript makes it easy to create variables in the global namespace. Creating a global variable is effortless because it does not require any form of declaration and can be automatically accessed by all code throughout the program.

For those of us who have encountered certain requirements (for example, the data being transmitted is recorded, waiting for a function call at some point, or a function is used frequently), it is not hesitate to think of global functions, even the first-to-most-learned C language-oriented process thinking is too ingrained, and the system is neatly full of functions. Defining a global variable pollutes the shared public namespace and can cause unexpected naming conflicts. Global variables are also not conducive to modularity, as it leads to unnecessary coupling between independent components in the program. Seriously, too much of the global (including style sheets, direct definition of div or A's style), integration into multiple-person development is a catastrophic error. That's why all of jquery's code is wrapped in an anonymous expression that executes immediately--from calling an anonymous function. When the browser finishes loading the jquery file, the self-invoke anonymous function begins execution immediately, initializing the various modules of jquery to avoid damaging and polluting the global variables and affecting other code.

(function (window,undefined) {    var jQuery = ...    //...    Window.jquery = window.$ = JQuery;}) (window);

In addition, you may think, "How to write first, and then organize later" is more convenient, but good programmers will constantly pay attention to the structure of the program, continuously classify the related functions and separation of unrelated components, and these behaviors as part of the programming.

Because the global namespace is the only way for independent components in a JavaScript program to interact with each other, it is unavoidable to take advantage of a globally named control. A component or library has to define some global variables. So that other parts of the program are used. Otherwise, it is best to use local variables.

This.foo;//undefinedfoo = "Global foo"; this.foo;//"Global foo" var foo = "Global foo"; this.foo = "changed"; foo;//change D

The global namespace of JavaScript is also exposed to global objects that can be accessed in the program's global scope, which acts as the initial value of the This keyword. In a Web browser, the global object is bound to the Global window variable. This means you can create a global variable by declaring it with VAR within the global scope, or by adding it to the global object. The benefit of using the Var declaration is that it can clearly express the effect of global variables in the program scope.

Because a global variable referenced as bound causes a run-time error, saving the scope is clear and concise, making it easier for the user of the code to understand that the program declares those global variables.

Because global objects provide a dynamic response mechanism for the global environment, you can use it to query a running environment to detect which features are available under this platform.

eg. ES5 introduces a global JSON object to read and write JSON-formatted data.

if (!this. JSON) {This   . JSON = {         parse: ...,         stringify: ...        }  }

If you provide the implementation of JSON, you can of course use your own implementation simply and unconditionally. But the built-in implementations provided by the hosting environment are almost more appropriate because they are written into the browser in the C language. Because they are rigorously checked for correctness and consistency according to certain standards , and generally provide better performance than third-party implementations.

The basic operation of the data structure course design simulation string requires that the method provided by the language itself cannot be used. The basic operation of the JavaScript array is very good, and if it's just a general learning need, the idea of simulating the language itself provides good ideas, but if you really put it into development, you don't have to consider the first time you choose to use JavaScript built-in methods.

1.2 Avoid using with

The WITH statement provides any "convenience" that makes your application unreliable and inefficient. We need to call a series of methods on a single object in turn. Using the WITH statement makes it easy to avoid duplicate references to objects:

function status (info) {    var widget = new Widget ();    With (widget) {           setbackground ("Blue");           Setforeground ("white");           SetText ("Status:" +info);           Show ();    }  }

It is also tempting to "import" variables from a module object using the WITH statement.

function f (x, y) {   with (Math) {         return min (round (x), sqrt (y));//Abstract Reference   }}

In fact, JavaScript treats all variables in the same way. JavaScript looks out for variables from the inside of the scope. The with language treats an object as if it represents a variable scope, so, inside the with code block, the variable lookup starts by searching for the property of the given variable name. If the property is not found in this object, the search continues in the external scope. A reference to each external variable in the With block implicitly assumes that there is no property of the same name in the With object (and any of its prototype objects). Creating or modifying a with object or its prototype object elsewhere in the program does not necessarily follow such assumptions. The JavaScript engine will of course not read the local code to get the local variables you used. JavaScript scopes can be represented as efficient internal data structures, and variable lookups can be very fast. But because the with code block needs to search the prototype chain of the object to find all the variables in the with code , it runs much faster than the normal block of code.

Instead of the with language, a simple practice is to bind an object to a short variable name.

function status (info) {    var w = new Widget ();         W.setbackground ("Blue");     W.setforeground ("white");     W.settext ("Status:" +info);     W.show ();   }

In other cases, the best approach is to explicitly bind local variables to related properties.

function f (x, y) {    var    min    = math.min,           round  = math.round,           sqrt   = math.sqrt;       return min (Round (x), sqrt (y));}

1.3 Mastering closures

Understanding closures has a single concept:

A) JavaScript allows you to reference variables defined outside of the current function.

function Makesandwich () {   var magicingredient = "Peanut butter";   function make (filling) {        return magicingredient + "and" + Filling;   }   return make ("Jelly");  } Makesandwich ();//"Peanut Butter and Jelly"

b) Even if an external function has returned, the current function can still refer to the variable defined in the external function

function Makesandwich () {   var magicingredient = "Peanut butter";   function make (filling) {        return magicingredient + "and" + Filling;   }   return  }var f = sandwichmaker (); F ("jelly");                      "Peanut Butter and Jelly" f ("Bananas");               "Peanut butter and Bananas" f ("Mallows");               "Peanut Butter and Mallows"

The function values of JAVASCRIPTD contain more information than is required to execute the code when they are called. Also, JavaScript function values are stored internally that they may reference variables that are defined in their enclosing scope. functions that track variables within the scope they cover are called closures .

The Make function is a closure whose code references two external variables: magicingredient and filling. Each time the Make function is called, its code can reference both variables because the closure stores the two variables.

A function can refer to any variable within its scope, including parameters and external function variables. We can use this to write more general-purpose sandwichmaker functions.

function Makesandwich (magicingredient) {     function make (filling) {        return magicingredient + "and" + Filling;   }   return make;  } var f = sandwichmaker ("Ham"); F ("cheese");                      "Ham and Cheese" f ("mustard");               "Ham and Mustard"

Closures are one of the most elegant and expressive features of JavaScript and are at the heart of many idiomatic usages.

c) Closures can update the values of external variables. In fact, closures store references to external variables , not copies of their values. Therefore, any closures that have access to these external variables can be updated.

function box () {    var val = undefined;    return {         set:function (newval) {val = newval;},         get:function () {return val;},         type:function () {return T Ypeof val;}}    ;} var b = box (); B.type (); Undefinedb.set (98.6); B.get ();//98.6b.type ();//number

This example produces an object that contains three closures. These three closures are set,type and get properties, both of which share access to the Val variable, and the set closure updates the Val value. The Get and type are then called to view the results of the update.

1.4 Understanding Variable Declaration elevation

JavaScript supports this method scope (the reference to the variable foo is bound to the scope that declares the Foo variable most recently), but the block-level scope is not supported (the scope of the variable definition is not the enclosing statement or block of code closest to it).

Not knowing this feature will result in some subtle bugs:

function Iswinner (player,others) {    var highest = 0;    for (var i = 0,n = Others.length; i<n;i++) {          var player = others[i];          if (Player.score > highest) {                   highest = Player.score;          }    }    return player.score > highest;}

1.5 Beware of named function expressions clumsy scopes

function double (x) {return x*2;} var f = function (x) {return x*2;}

The same function code can also act as an expression, but with a different meaning. The official difference between an anonymous function and a named function expression is that the latter is bound to a variable with the same name as its function, which acts as a local variable for the function. This can be used to write recursive function expressions.

var f = function Find (tree,key) {  //....  Return find (Tree.left, key) | |              Find (Tree.right,key);    }

It is worth noting that the scope of the variable find is only in its own function, unlike a function declaration, a named function expression cannot be referenced in the external part by its internal function name.

var constructor = function () {return null;} var f= function () {    return constructor ();}; f ();//{} (in ES3 environments)

The program will appear to produce null, but it will actually produce a new object.

Because the named function variable is scoped to inherit the Object.prototype.constructor (that is, the Oject constructor), as with the With statement, the scope is affected by the dynamic change of the object.prototype. The way to avoid object contamination function expression scopes in the system is to avoid adding properties to object.prototype at any time to avoid using any local variables with the same name as the standard Object.prototype property.

Another disadvantage of the popular JavaScript engine is the promotion of the Declaration of a named function expression.

var f = function g () {return 17;} g (); (in Nonconformat Environment)

Some JavaScript environments even use the two functions of F and G as different objects, resulting in unnecessary memory allocations.

1.6 Beware of local block functions declaring awkward scopes

function f () {return "global";} function  Test (x) {    function f () {return "local";}    var result = [];    if (x) {         result.push (f ());    }           Result.push (f ());     result result;} Test (true);   ["Local", "local"]test (false);  ["Local"]
function f () {return "global";} function  Test (x) {       var result = [];    if (x) {         function f () {return "local";}         Result.push (f ());           Result.push (f ());     result result;} Test (true);   ["Local", "local"]test (false);  ["Local"]

JavaScript does not have a block-level scope, so the scope of the intrinsic function f should be the entire test function. Some JavaScript environments do, but not all JavaScript environments, where JavaScript implementations report such functions as errors in strict mode (Programs in strict mode with local block function declarations are reported as a syntax error). Helps detect non-portable code for future standard versions in giving local block function declarations to be more sensible and can be semantically. For this scenario, consider declaring a local variable within the test function to point to the global function F.

Write high-quality JS code on

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.