Introduction to private/static attributes in JavaScript

Source: Internet
Author: User

• Simulate block-level scope
We all know that there is no block-level scope concept in JavaScript. We can simulate block-level scope by using closures. See the following example:
Copy codeThe Code is as follows:
(Function (){
For (var I = 0; I <10; I ++ ){
// Do Nothing
}
Alert (I); // output 10
})();

The variable I in the for loop block can be accessed in Row 3. If we slightly modify the above Code and place the for loop block in the closure, the situation will be different:
Copy codeThe Code is as follows:
(Function (){
(Function (){
For (var I = 0; I <10; I ++ ){
// Do Nothing
}
})();
Alert (I); // Error: 'I' is undefined
})();

The block-level scope we want is implemented due to an error when the access to line 1 Changes to I.
• Private attributes
There is no block-level scope concept in JavaScript, and there is also no private attribute concept, but there is a private variable. What should we do if we want to hide some data? As you may have already thought, you can use closures + private variables to implement private attributes of objects.
<1>. Private attributes of the Instance
The private attribute of an instance is that each object contains an independent attribute, and the object is not shared. To achieve this goal, you can add a private variable to the constructor and define a public method to access this private variable, just like setter and getter in other OO languages, the following example implements the private attributes of an instance:
Copy codeThe Code is as follows:
// Private variable of the Instance
Function MyObject (name ){
// Define private variables
// Note: this. name is not used here. If this. name is used, it becomes a public attribute.
Var privateName = name;
// Define private familiarity
Var privateFunction = function (){
Return "Private Function ";
}
// Public method access private
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 getName of the two objects moGyy and moCyy created in the preceding example returns different values. If you want to call a private method, you also need a public interface. In the preceding example, two public functions can access private variables because both public functions are closures, and the scope chain of closure contains variable objects containing functions, therefore, when searching for variables, you can access private variables in the function following the scope chain. In the preceding example, the public method is added to the prototype of MyObject to prevent two function instances with the same functions from being created each time an object is created.
<2>. Static private attributes
In some cases, we may want to share data globally, so static attributes may be used. We still want this attribute to be private. How can we implement static private attributes? First, this private should be outside the constructor. To integrate the variables outside the constructor with the constructor, you can use closures to include both private variables and constructor in their scopes, to access the internal constructor outside the closure, you can use a global variable to reference the constructor. The following code example:
Copy codeThe Code is as follows:
// Static private variables and instance private variables
(Function (){
// Define private variables
Var staticPrivateValue = "";
// Constructor, which assigns a texture function to a global variable
MyObject = function (name ){
// Define instance variables
This. name = name;
};
// Define two public methods to access private variables and add them to the prototype again.
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 the Private Attribute
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); // outputs jeff-cyy

From the code above, mo1 calls the getPrivateValue function and returns the value "gyycyy" set by mo. Why? First, we define an anonymous function and call it immediately. The function contains the private variable staticPrivateValue, the two prototype methods defined for MyObject can actually access private variables including functions through the scope chain of closures, that is, the scope chains of the getPrivateValue and setPrivateValue functions contain variable objects of anonymous functions. We know that the variable objects contained in the scope chain are actually a pointer, therefore, when two objects are created using the public method to house private variables, they actually access staticPrivateValue in the variable object of the anonymous function, so the purpose of sharing variable instances is realized. From the perspective of traditional OO language, the static attributes we implement are not static in the true sense, but share static attribute instances.
<3>. Module mode and enhancement module Mode
Singleton is another way to share data globally. You can use the module mode to implement the Object-type singleton mode, or you can use the enhanced module mode to implement the custom type singleton mode, example:
Copy codeThe Code is as follows:
// Custom Constructor
Var mo = new function (){
// Private variable
Var privateValue = "";
// Common module Mode
Return {
PublicValue: "public ",
// Access private variables
GetPrivateValue: function (){
Return privateValue;
},
SetPrivateValue: function (value ){
PrivateValue = value;
}
}
}();
Mo. setPrivateValue ("private value ");
Alert (mo. getPrivateValue ());
Alert (mo. publicFunction ());

The module mode uses anonymous functions to encapsulate internal implementations. In the preceding example, an anonymous function contains the private variable privateValue. The public functions in the returned object access the private variables in the function through the scope chain of the closure, because the defined anonymous function is called immediately, the variable mo references the returned object. The preceding Singleton mode returns an Object. You can use the enhancement module mode to implement a custom Singleton mode:
Copy codeThe Code is as follows:
// Enhance the module Mode
// Custom Constructor
Function MyObject (name ){
This. name = name;
};
// Custom Constructor
Var mo = new function (){
// Private variable
Var privateValue = "";
// Enhance the module Mode
Var o = new MyObject ("gyycyy ");
O. publicValue = "public ";
// Access 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 preceding code example implements the singleton mode of MyObject.
The last thing to note is that the use of closures has both advantages and disadvantages. Because the closure scope chain references variable objects containing functions, it will occupy additional memory, in addition, you also need to use the scope chain for Variable Search, which consumes the search time. The deeper the closure, the more severe the condition. In addition, in IE (earlier versions), because the garbage collection mechanism uses reference counting, it may cause loop reference, resulting in Memory leakage, as shown in the following example:
Copy codeThe Code is as follows:
Function assignHandler (){
Var element = document. getElementById ("someElement ");
Element. onclick = function (){
Alert (element. id );
};
}

In the above Code, a closure is created as an element event, which references a variable object containing the assingHandler function. The reference to the variable object makes the element reference count at least 1, therefore, the element will not be recycled, causing memory leakage. You can think about the modification method.

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.