JavaScript does not have a special syntax to represent the private properties and methods of an object, and by default all properties and methods are public. Objects that are literally declared as follows:
var myobj = { myprop:1, getprop:function () { return this.myprop; }}; Console.log (Myobj.myprop); ' MyProp ' is publicly Accessibleconsole.log (Myobj.getprop ()); Getprop () is public too
Also, the following objects are declared with the constructor function:
function Gadget () { this.name = ' iPod '; This.stretch = function () { return ' IPad '; };} var toy = new Gadget (); Console.log (Toy.name); ' Name ' is Publicconsole.log (Toy.stretch ()); Stretch () is public
1. Private membersAlthough JavaScript does not provide a syntax representation of a private member, it provides a local scope through a local code snippet (closure) to implement a private member. The only way to provide a local scope in JavaScript is a function. For example, a variable declared using var inside a constructor is a private variable. We can then access these variables through public methods: the effect is the same as access control in Java:
function Gadget () { //Private member var name = ' IPod '; Public function This.getname = function () { return name; };} var toy = new Gadget ();//' name ' is undefined, it ' s privateconsole.log (toy.name); undefined//public method have access to ' name ' Console.log (Toy.getname ()); "IPod"
The code above shows the methods that implement private members in JavaScript, which are local (private) for constructors and objects that will be constructed, but are not visible to the outside.
2. Privileged MethodsThe so-called privileged methods do not actually have a special syntax representation, but rather a means to provide private variable access to the outside. For example, the GetName () method in the above code is a privileged method that provides access control over the private property name.
3. Invalidation of access control for private membersAccess control for private members can also be invalidated, and commonThe situation is as follows:
- Earlier versions of Firefox provided the second parameter to eval (), allowing private members of the function to be accessed;
- Mozilla Rhino provides the __parent__ property to access the private members of the function;
- When a privileged method directly returns a reference to a private property that is exactly another object (an array is also an object), the external code can modify the object's contents through the object reference.
The above two cases are not implemented in the current mainstream browser, the most need to guard against is the third situation, such as the following code:
function Gadget () { //Private member var specs = { Screen_width: + , screen_height:480, Color: "White" }; Public function this.getspecs = function () { return specs; };}
Getspecs () returns a reference to the Specs object, where the external code not only gets the values stored in the Specs object, but also modifies the values at any time:
var toy = new Gadget (), specs = Toy.getspecs (); specs.color = "BLACK"; specs.price = "free"; Console.dir (Toy.getspecs ( ));
You can imagine what the result of the above Console.dir returned. To prevent the private member access control from being invalidated by the object reference, do not return the private member's reference directly. The workaround can be to return a cloned object, or to return only the numeric value of the simple data type that needs to be returned in the private member. The latter is also known as Principle of Least Authority (POLA). For example, in the example above, if the user of the Code calls Getspecs () to get the size of the gadget, then you can provide a getdimensions () method that returns a new (new) object with width and height. If you do not want to return a specs object, you can also return a copy of the specs by another implemented clone method. Many JavaScript libraries provide APIs such as extend () or extenddeep (), enabling shallow and deep copies of objects.
4. Private members in an object that is literally declaredThe above describes the private members of the object when using the constructor, and objects created using literal notation can also implement private members, in the same way that the local scope of the function is used to provide local (private) variables. Then we need to use an immediate function:
var myobj; This would be is the object (function () { //private members var name = "My, Oh my"; Implement the public part //NOTE--no ' var ' myobj = { //Privileged Method Getname:function () {
return name;}} ;} ()); Myobj.getname (); "My, Oh My"
If the new object is returned with an immediate function, the effect is the same:
var myobj = (function () { //private members var name = "My, Oh my"; Implement the public part return { getname:function () { return name;}} ;} ()); Myobj.getname (); "My, Oh My"
This kind of writing is actually the initial implementation of the module mode, here first mention, and then detailed introduction.
5. Prototype and private membersA less-than-perfect place to declare a private member with a local variable or method is that these local properties and methods are created once each time the object is created. This problem also occurs when you use this to add a member property to an object in a constructor. The workaround is to put the usual members (both public and private) in the PROTOYTPE, so that the member properties and methods are created only once. The following implementations use two modes: the pattern of implementing a private property in a constructor and the implementation of a private property in an object that is literally declared. Private properties created in the literal declaration of prototype are assigned to each object that will be created, and only prototype is initialized once.
function Gadget () { //Private member var name = ' IPod '; Public function This.getname = function () { return name; };} Gadget.prototype = (function () { //Private member var browser = "Mobile Webkit"; Public prototype members return { getbrowser:function () { return browser;}} ;} ()); var toy = new Gadget (); Console.log (Toy.getname ()); Privileged "own" Methodconsole.log (Toy.getbrowser ()); Privileged Prototype method
6. Disclosure Pattern (Revelation pattern): Turning private methods into publicwe can expose private methods to public interfaces on any pattern that implements private methods. This mode can provide access to private methods while protecting private methods. The following is an implementation:
var myarray; (function () { var astr = "[Object Array]", toString = Object.prototype.toString; function IsArray (a) { return Tostring.call (a) = = = Astr; } function indexOf (haystack, needle) { var i = 0, max = haystack.length; for (; i < max; i + = 1) { if (haystack[i] = = = needle) { return i; } } return 1; } MyArray = { Isarray:isarray, indexof:indexof, inarray:indexof };} ());
The code above provides a public interface for private methods of objects created using literal notation. Similarly, you can implement this pattern when you create an object using a constructor. In the above code, IsArray () and indexOf () are private methods, while the literal declaration provides two public interfaces for IndexOf (): JavaScript-style indexOf () and PHP-style inarray (). These two public interfaces are used in exactly the same way:
Myarray.isarray ([up]); Truemyarray.isarray ({0:1}); Falsemyarray.indexof (["A", "B", "Z"], "Z"); 2myarray.inarray (["A", "B", "Z"], "Z"); 2
With this model, one but the outside program modifies the public interface, the internal private implementation will not be affected. For example, modify the public indexof () interface and point it to null without affecting the use of inarray ():
Myarray.indexof = Null;myarray.inarray (["A", "B", "Z"], "Z"); 2
JavaScript Base Object creation mode private properties and methods (024)