• Simulate block level scopes
As we all know there is no block-level scope in JavaScript, we can simulate block-level scopes by using closures, see the following example:
Copy Code code as follows:
(function () {
for (var i = 0; i < i++) {
Doing nothing
}
alert (i); Output 10
})();
Line 6th can access the variable i in the For loop block, and if we modify the above code slightly, the for loop block is placed in the closure, and the situation is different:
Copy Code code as follows:
(function () {
(function () {
for (var i = 0; i < i++) {
Doing nothing
}
})();
alert (i); Error: ' I ' is undefined
})();
When the 8th row accesses change I, there is an error, which implements the block-level scope that we want.
• Private properties
There is no notion of a block-level scope in JavaScript, nor is there a concept of a private property, but there are private variables. What do we do if we want to hide some data encapsulation? As you may have thought, you can implement private properties of objects by using closures + private variables.
<1> Instance private property
The characteristic of an instance private property is that each object contains a separate property, and there is no sharing between the object and the object. To achieve this goal, you can add a private variable to the constructor and then define a public method to access the private variable, just as the setter and getter of other OO languages implement the private properties of the instance:
Copy Code code as follows:
Instance private variable
function MyObject (name) {
Defining private variables
Note: THIS.name is not used here, if you use THIS.name to become a public property
var privatename = name;
Defining private familiarity
var privatefunction = function () {
Return "Private Function";
}
Public method Access Private familiarity
MyObject.prototype.getName = function () {
return privatename;
}
MyObject.prototype.getFunction = function () {
return Privatefunction ();
}
}
var mogyy = new MyObject ("Gyy");
Alert (Mogyy.getname ()); Output Gyy
Alert (Mogyy.getfunction ()); Output Private Function
var mocyy = new MyObject ("Cyy");
Alert (Mocyy.getname ()); Output CYY
Alert (Mocyy.getfunction ()); Output Private Function
The two objects created in the previous example Mogyy and Mocyy getname return different values, and the public interface is also required if you want to invoke a private method. Two common functions in the above example have access to private variables because two common functions are closures, and the scope chain of closures contains variable objects containing functions, so when you do a variable lookup, you can access the private variable in the containing function along the scope chain. In the previous example, the public method was added to the MyObject prototype to prevent the creation of two function instances of the same function each time the object was created.
<2> static private properties
In some cases we might want the data to be shared globally, then we might use static properties, and we still want this property to be private, so how do we implement the static private property? First this private should be outside of the constructor, to combine variables and constructors that are external to the constructor, you can use closures to include both private variables and constructors in their scope, and in order to access the internal constructors outside the closure, you can use a global variable to refer to the constructor, as in the following code example:
Copy Code code as follows:
Static private variables and instance private variables
(function () {
Defining private variables
var staticprivatevalue = "";
constructor, assigning the texture function to a global variable
MyObject = function (name) {
Defining instance Variables
THIS.name = name;
};
Defines two public methods for accessing private variables, once again adding public methods to the prototype
MyObject.prototype.getPrivateValue = function () {
return staticprivatevalue;
}
MyObject.prototype.setPrivateValue = function (value) {
Staticprivatevalue = value;
}
})();
var mo = new MyObject ("Jeff-gyy");
Mo.setprivatevalue ("Gyycyy"); Set the value of a private property
Alert (Mo.getprivatevalue ()); Output GYYCYY
alert (mo.name); Output Jeff-gyy
var mo1 = new MyObject ("Jeff-cyy");
Alert (Mo1.getprivatevalue ()); Output GYYCYY
alert (mo1.name); Output JEFF-CYY
From the code above, the value returned by the MO1 call Getprivatevalue function is the value of Mo set "Gyycyy." First we define an anonymous function and call the function immediately, and the function contains the private variable staticprivatevalue, so the two prototype methods defined for MyObject actually access the private variable that contains the function through the scope chain of the closure. That is, the scope chain of the getprivatevalue and Setprivatevalue two functions contains the variable object of the anonymous function, and we know that the variable object contained in the scope chain is actually a pointer, so the two objects created by the public method house private variable, In fact, the access is the Staticprivatevalue of the variable object of the anonymous function, so the purpose of sharing the variable instances is realized. From the point of view of traditional OO language, the static property of our implementation is not static in real sense, but the characteristic of static property instance sharing is realized.
<3>. module mode and enhanced module mode
Another way to share data globally is singleton, which enables you to implement a single case pattern of type object using module mode, or you can use an enhanced module pattern to implement a single example pattern of a custom type, as shown in the following example:
Copy Code code as follows:
Custom constructors
var mo = new function () {
Private variable
var privatevalue = "";
Normal module mode
return {
Publicvalue: "Public",
Accessing private variables
Getprivatevalue:function () {
return privatevalue;
},
Setprivatevalue:function (value) {
Privatevalue = value;
}
}
}();
Mo.setprivatevalue ("Private value");
Alert (Mo.getprivatevalue ());
Alert (Mo.publicfunction ());
Module mode uses an anonymous function to encapsulate an internal implementation, and the example anonymous function above contains the private variable Privatevalue, where the public function in the returned object accesses the private variable in the containing function through the scope chain of the closure, because the defined anonymous function is called immediately. Therefore, the variable Mo refers to the returned object. The single example pattern above returns an object that can be used to implement a custom type in an enhanced module mode:
Copy Code code as follows:
Enhanced Module mode
Custom constructors
function MyObject (name) {
THIS.name = name;
};
Custom constructors
var mo = new function () {
Private variable
var privatevalue = "";
Enhanced Module mode
var o = new MyObject ("Gyycyy");
O.publicvalue = "public";
Accessing private variables
O.getprivatevalue = function () {
return privatevalue;
}
O.setprivatevalue = function (value) {
Privatevalue = value;
}
return o;
}();
Mo.setprivatevalue ("Private value");
Alert (Mo.getprivatevalue ());
Alert (Mo.publicfunction ());
The above code example implements the MyObject of a single case pattern.
The last thing to mention is that there are advantages to using closures, because the closure scope chain refers to the variable object that contains the function, so it takes up extra memory, and the variable lookup is also through the scope chain, so it consumes the lookup time and the deeper the closure. In addition, in IE (earlier versions) because the garbage collection mechanism uses reference counting, a circular reference may occur that could result in a memory leak, as in the following example:
Copy Code code as follows:
function Assignhandler () {
var element = document.getElementById ("someelement");
Element.onclick = function () {
alert (element.id);
};
}
In the above code, you create an event with a closure as an element that references a variable object that contains the function assinghandler, whereas a reference to a variable object makes the element reference count at least 1, so that the element is not reclaimed, resulting in a memory leak. Modify the method you can think about.