Content Highlights:
Concept of function scope: variables declared in a function are visible throughout the body of the function (including in nested functions), which is invisible outside the function. Variables that are not declared in any function are global variables and are visible throughout the JS program.
In JS, you cannot declare variables that are visible only within a block of code. (In the client JS this is not entirely correct, for example, in some JS extension can be used to declare the variables within the statement block)
For this reason, we often simply define a function to be used as a temporary namespace, and the variables defined within that namespace will not contaminate the global namespace.
For example, suppose you write a JS module code, this code will be used in a different JS program (for the client JS is usually used in a variety of web pages). As with most code, it is assumed that this code defines a variable that stores the results of an intermediate calculation. The problem is that when the module code is running in a different program, you can't tell if the variable has been created, and if the variable already exists, it will conflict with the code.
The workaround is to put the code inside a function and call the function. The global variable becomes a local variable within the function.
I. Defining anonymous functions and calling them immediately in a single expression
(function () {
Module code
}()); End the function definition and call it immediately
It is common to define anonymous functions and invoke them immediately in a single expression, which has become a customary method.
In the following example, this namespace technique is shown. It defines an anonymous function that returns the Extend () function, and the code in this anonymous function detects whether a well-known IE bug occurs and returns a patched version of the function if this bug occurs. In addition, this anonymous function namespace is used to hide a set of property names.
Cases:
Returns the Extend () version with patches in a specific scenario
Define an extension function to copy the second and subsequent parameters to the first argument
If the property of O has a property of the same name that cannot be enumerated, the For/in loop does not enumerate the enumerable properties of the object o, that is, properties such as ToString will not be processed correctly unless we explicitly detect it
var extend = (function () {//assigns the return value of this function to extend
Before you fix it, check for bugs first
For (Var p in {Tostring:null}) {
If the code executes here, then the for/in loop will work correctly and return
A simple version of the Extend () function
return function Extend (o) {
for (Var i=1;i<arguments.length;i++) {
var source = Arguments[i];
For (Var prop in source) O[prop] =source[prop];
}
return o;
};
}
If the code executes here, the for/in loop does not enumerate the ToString property of the test object
Therefore, another version of the Extend () function is returned, and this function explicitly tests
Non-enumerable properties in Object.prototype
return function Patched_extend (o) {
for (Var i=1;i<arguments.length;i++) {
var source=arguments[i];
Copy all enumerable properties
For (Var prop in source) O[prop] = Source[prop];
Now check for special properties
for (Var j=0;j<protoprops.length;j++) {
Prop = Protoprops[j];
if (Source.hasownproperty (prop)) O[prop] = Source[prop];
}
}
return o;
};
var protoprops = ["ToString", "ValueOf", "constructor", "hasOwnProperty", "isprototypeof", "propertyisenumrable", " toLocaleString "];
}());
var h ={x:1,y:2,z:3};
var s = Extend (h);
Console.log (s); Object {x=1, y=2, z=3}
Console.log (s.x); 1
JS Authoritative Guide Learning summary--8.5 as a function of the namespace