How to write high quality JS code _ Basic Knowledge

Source: Internet
Author: User
Tags anonymous closure data structures variable scope advantage

Want to write efficient JavaScript class library but not the start;

Try to read other people's class library, but understand it like to understand;

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

Even remember "use", but to "use" when there is no thought of "law."

Maybe you and I, like a look at the invisible force of the constraints of our plans, let us repeatedly think that the limitations of knowledge, so that we stand still, it is difficult to leap forward.

This period of time, a variety of assignments, curriculum design, experimental reports, pressure doubled. Hard to squeeze a little bit of time, never sleep late, collation summed up the past to read the book, just to be able to write their own class library near a point.

This article is based on the JavaScript language essence and effective JavaScript. Examples have been debugged, after understanding, I would like to put some "esoteric" reason to speak a little bit.

1. Variable Scope

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

1.1 Use global variables as little as possible

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

For all of us beginners, when some requirements are encountered (for example, when the transmitted data is recorded, waiting for a certain function to be invoked, or when a function is used frequently), it is not hesitant to think of global functions, or even the C-language-oriented process thought of a freshman is too ingrained, and the system is full of functions. Defining a global variable pollutes the shared public namespace and can result in unexpected naming conflicts. Global variables are also not conducive to modularity because they cause unnecessary coupling between independent components in a program. Seriously, too much of the global (including stylesheets, direct definition of div or a style), integration into many people has been developed will be a disastrous error. That's why all the code in jquery is wrapped in an anonymous expression that executes immediately--a call to an anonymous function. When the browser finishes loading the jquery file, the call anonymous function starts immediately, initializing the various modules of jquery to avoid damaging and polluting the global variable so that it affects other code.

Copy Code code as follows:

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

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

Because global namespaces are the only way to interact with separate components in a JavaScript program, it is unavoidable to take advantage of global naming controls. A component or library has to define some global variables. For use in other parts of the program. Otherwise, it is best to use local variables.

Copy Code code as follows:

This.foo;//undefined.
foo = "Global foo";
This.foo//"Global foo"
var foo = "Global foo";
This.foo = "Changed";
foo;//changed

The global namespace of JavaScript is also exposed to global objects that can be accessed in the program global scope, which acts as the initial value of the This keyword. In a Web browser, global objects are bound to global window variables. This means that you can create global variables in two ways: declare him with VAR in the global scope, or add it to the global object. The advantage of using the Var declaration is that it clearly expresses the impact of global variables in the scope of the program.

Since a reference to a binding global variable can result in a run-time error, saving the scope clearly and succinctly makes 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 introduced a global JSON object to read and write JSON-formatted data.

Copy Code code as follows:

if (!this. JSON) {
This. JSON = {
Parse:..,
Stringify: ...
}
}

If you provide the implementation of JSON, you can of course use your own implementations 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 C language. Because they are rigorously checked for correctness and consistency by a certain standard, they generally provide better performance than Third-party implementations.

The original data structure course design simulates the basic operation of the string, the request cannot use the method provided by the language itself. The basic operation of JavaScript arrays is very good, and if it is only for general learning needs, the analog language itself provides a good idea of the method, but if really put into development, do not need to consider the first time to 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 repeating references to objects:

Copy Code code as follows:

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

It is also tempting to use the With statement to "import" variables from a module object.

Copy Code code as follows:

function f (x,y) {
With (Math) {
return min (Round (x), sqrt (y));//Abstract reference
}
}

As a matter of fact, JavaScript treats all variables the same. JavaScript starts out looking for variables from the most inner scope. The with language treats an object as if it represents a variable scope, so within the with code block, the variable lookup begins with the search for the property of the given variable name. If the attribute is not found in this object, the search continues in the external scope. The 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 in other parts of the program does not necessarily follow this assumption. The JavaScript engine certainly does not read local code to get the local variables that you use. JavaScript scopes can be represented as efficient internal data structures, and variable lookups can be very fast. However, 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 slower than the normal code block.

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

Copy Code code as follows:

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.

Copy Code code as follows:

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

1.3 Proficiency in closure

Understanding closures have a single concept:

A javascript allows you to reference variables defined outside the current function.

Copy Code code as follows:

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

b even if the external function has returned, the current function can still refer to the variable defined by the external function

Copy Code code as follows:

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

JAVASCRIPTD's function values contain more information than the code needed to execute when they are invoked. Also, JavaScript function values internally store variables that they might refer to that are defined in their enclosing scope. The functions that track variables within the scope they cover are called closures.

The Make function is a closure whose code refers to two external variables: magicingredient and filling. Each time the Make function is invoked, its code can refer to both variables, because the closures store 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 Sandwichmaker functions.

Copy Code code as follows:

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 idioms.

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.

Copy Code code as follows:

function box () {
var val = undefined;
return {
Set:function (newval) {val = newval;},
Get:function () {return val;},
Type:function () {return typeof Val;}
};
}
var b = box ();
B.type (); Undefined
B.set (98.6);
B.get ();//98.6
B.type ();//number

This example produces an object that contains three closures. These three closures are set,type and get properties that share access to the Val variable, and the set closure updates Val's value. Then call get and type to see the results of the update.

1.4 Understanding Variable Declaration Promotion

JavaScript supports this scope (references to variable foo are bound to the most recent scope of declaring Foo variables), but block-level scopes are not supported (the scope of a variable definition is not the closest enclosing statement or block of code).

Not understanding this feature will result in some subtle bugs:

Copy Code code as follows:

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 the awkward scope of a named function expression

Copy Code code as follows:

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

The same function code can also be used as an expression, but it has very different meanings. 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 of that function. This can be used to write recursive function expressions.

Copy Code code as follows:

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

It is noteworthy that the scope of the variable find is only in its own function, unlike function declarations, and that a named function expression cannot be referenced by the outer part of its internal function name.

Copy Code code as follows:

Find (Mytree, "foo");//error:find are not defined;
var constructor = function () {return null;}
var f= function () {
return constructor ();
};
f ();//{} (in ES3 environments)

The program appears to produce null, but it actually produces a new object.

Because the Object.prototype.constructor (that is, the Oject constructor) is inherited within the scope of a named function variable, as with a statement, this scope is affected by the dynamic change of Object.prototype. The way to avoid object-contaminated function expression scopes in a 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 in the popular JavaScript engine is the elevation of the declaration of a named function expression.

Copy Code code as follows:

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

Some JavaScript environments even take the functions of f and G as different objects, resulting in unnecessary memory allocations.

1.6 Beware the local block function declares the awkward scope

Copy Code code as follows:

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"]

Copy Code code as follows:

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 block-level scopes, so the scope of the internal function f should be the entire test function. Some JavaScript environments do, but not all JavaScript environments, JavaScript implementations report such functions in strict mode as errors (Programs in strict mode with local block function declarations will report as a syntax error), Helps detect non portable code, and makes it more sensible and semantic for future standard versions to declare local block functions. In this case, consider declaring a local variable in the test function to point to the global function F.

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.