JavaScript Patterns 5.3 Private Properties and Methods
2014-06-25 12:31
495 查看
All object members are public in JavaScript.
The same is true when you use constructor functions to create objects.
Private Members
Implement private members using a closure.
Privileged Methods
it’s just a name given to the public methods that have access to the private members (and hence have more privileges).
In the previous example, getName() is a privileged method because it has “special” access to the private property name.
Privacy Failures
• When you’re directly returning a private variable from a privileged method and this variable happens to be an object or array, then outside code can modify the private variable because it’s passed by reference.
/*
*/
Solutions
Principle of Least Authority (POLA):
Return a new object containing only some of the data that could be interesting to the consumer of the object.
Another approach, when you need to pass all the data, is to create a copy of the specs object, using a general-purpose object-cloning function.
Object Literal and Privacy
Prototypes and Privacy
One drawback of the private members when used with constructors is that they are recreated every time the constructor is invoked to create a new object. To solve this you can add common properties and methods to the prototype property of the constructor.
Revealing Private Functions As Public Methods
Now if something unexpected happens, for example, to the public indexOf(), the private indexOf() is still safe and therefore inArray()will continue to work:
References:
JavaScript Patterns - by Stoyan Stefanov (O`Reilly)
var myobj = { myprop : 1, getProp : function() { return this.myprop; } }; console.log(myobj.myprop); // `myprop` is publicly accessible console.log(myobj.getProp()); // getProp() is public too
The same is true when you use constructor functions to create objects.
// all members are still public: function Gadget() { this.name = 'iPod'; this.stretch = function() { return 'iPad'; }; } var toy = new Gadget(); console.log(toy.name); // `name` is public console.log(toy.stretch()); // stretch() is public
Private Members
Implement private members using a closure.
function Gadget() { // private member var name = 'iPod'; // public function this.getName = function() { return name; }; } var toy = new Gadget(); // `name` is undefined, it's private console.log(toy.name); // undefined // public method has access to `name` console.log(toy.getName()); // "iPod"
Privileged Methods
it’s just a name given to the public methods that have access to the private members (and hence have more privileges).
In the previous example, getName() is a privileged method because it has “special” access to the private property name.
Privacy Failures
• When you’re directly returning a private variable from a privileged method and this variable happens to be an object or array, then outside code can modify the private variable because it’s passed by reference.
function Gadget() { // private member var specs = { screen_width : 320, screen_height : 480, color : "white" }; // public function this.getSpecs = function() { return specs; }; } var toy = new Gadget(), specs = toy.getSpecs(); specs.color = "black"; specs.price = "free"; console.dir(toy.getSpecs());
/*
color | "black" |
price | "free" |
screen_height | 480 |
screen_width | 320 |
Solutions
Principle of Least Authority (POLA):
Return a new object containing only some of the data that could be interesting to the consumer of the object.
Another approach, when you need to pass all the data, is to create a copy of the specs object, using a general-purpose object-cloning function.
Object Literal and Privacy
var myobj; // this will be the object ( function() { // private members var name = "my, oh my"; // implement the public part // note -- no `var` myobj = { // privileged method getName : function() { return name; } }; }()); var myobj = ( function() { // private members var name = "my, oh my"; // implement the public part return { getName : function() { return name; } }; }()); myobj.getName(); // "my, oh my"
Prototypes and Privacy
One drawback of the private members when used with constructors is that they are recreated every time the constructor is invoked to create a new object. To solve this you can add common properties and methods to the prototype property of the constructor.
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" method console.log(toy.getBrowser()); // privileged prototype method
Revealing Private Functions As Public Methods
var myarray; (function () { var astr = "[object Array]", toString = Object.prototype.toString; // private method function isArray(a) { return toString.call(a) === astr; }) // private method function indexOf(haystack, needle) { var i = 0, max = haystack.length; for (; i < max; i += 1) { if (haystack[i] === needle) { return i; } } return−1; } myarray = { // public methods isArray: isArray, indexOf: indexOf, inArray: indexOf }; }()); myarray.isArray([1, 2]); // true myarray.isArray({ 0: 1 }); // false myarray.indexOf(["a", "b", "z"], "z"); // 2 myarray.inArray(["a", "b", "z"], "z"); // 2
Now if something unexpected happens, for example, to the public indexOf(), the private indexOf() is still safe and therefore inArray()will continue to work:
myarray.indexOf = null; myarray.inArray(["a", "b", "z"], "z"); // 2
References:
JavaScript Patterns - by Stoyan Stefanov (O`Reilly)
相关文章推荐
- Javascript Module pattern template. Shows a class with a constructor and public/private methods/properties. Also shows compatibility with CommonJS(eg Node.JS) and AMD (eg requireJS) as well as in a br
- Javascript Object Method Properties console.log View all methods and properties of the object
- [JavaScript] Function Properties and Methods
- Objective-C Primer(2)Private Methods and Class Properties
- 非深入探寻Java反射机制: Private Fields and Private Methods
- Javascript set and get methods Textarea cursor position
- Microsoft.XMLDOM(XMLDOM)对象的属性和方法(Methods and properties of Microsoft.XMLDOM)
- HTML DOM Properties and Methods
- Microsoft.XMLDOM(XMLDOM)对象的属性和方法(Methods and properties of Microsoft.XMLDOM)
- OOP in JS Public/Private Variables and Methods
- [Groovy] Private fields and methods are not private in groovy
- Math object's properties and methods
- [Javascript] Log Levels and Semantic Methods
- The Boolean object's properties and methods
- Xrm.Page.data.entity Properties and Methods
- [Javascript] Chaining the Array map and filter methods
- Java Reflection - Private Fields and Methods
- OOP in JS, Part 1 : Public/Private Variables and Methods
- String object's properties and methods
- OOP in JS, Part 1 : Public/Private Variables and Methods