JavaScript: The Definitive Guide, Sixth Editio javaScript权威指南(第6版) pdf 文字版-文字版, javascript电子书, 和javascript 有关的电子书:

9.6.6 Private State

9.6.6 Private State


In classical object-oriented programming, it is often a goal to encapsulate or hide the state of an object within the object, allowing access to that state only through the methods of the object, and now allowing the important state variables to be read or written directly. To achieve this goal, languages like Java allow the declaration of “private” instance fields of a class that are only accessible to the instance method of the class and cannot be seen outside of the class.

We can approximate private instance fields using variables (or arguments) captured in the closure of the constructor invocation that creates an instance. To do this, we define functions inside the constructor (so they have access to the constructor’s arguments and variables) and assign those functions to properties of the newly created object. Example 9-10 shows how we can do this to create an encapsulated version of our Range class. Instead of having from and to properties that give the endpoints of the range, instances of this new version of the class have from and to methods that return the endpoints of the range. These from() and to() methods are defined on the individual Range object and are not inherited from the prototype. The other Range methods are defined on the prototype as usual, but modified to call the from() and to() methods rather than read the endpoints directly from properties.

Example 9-10. A Range class with weakly encapsulated endpoints

function Range(from, to) {

// Don't store the endpoints as properties of this object. Instead

// define accessor functions that return the endpoint values.

// These values are stored in the closure.

this.from = function() { return from; };

this.to = function() { return to; }; }

// The methods on the prototype can't see the endpoints directly: they have // to invoke the accessor methods just like everyone else. Range.prototype = {

constructor: Range,

includes: function(x) { return this.from() <= x && x <= this.to(); },

foreach: function(f) {

for(var x=Math.ceil(this.from()), max=this.to(); x <= max; x++) f(x);

},

toString: function() { return "(" + this.from() + "..." + this.to() + ")"; } };

This new Range class defines methods for querying the endpoints of a range, but no methods or properties for setting those endpoints. This gives instances of this class a kind of immutability: if used correctly, the endpoints of a Range object will not change after it has been created. Unless we use ECMAScript 5 features (see §9.8.3 ), however, the from and to properties are still writable, and Range objects aren’t really immutable at all:

var r = new Range(1,5); // An "immutable" range r.from = function() { return 0; }; // Mutate by replacing the method

Keep in mind that there is an overhead to this encapsulation technique. A class that uses a closure to encapsulate its state will almost certainly be slower and larger than the equivalent class with unencapsulated state variables.

欢迎转载,转载请注明来自一手册:http://yishouce.com/book/1/27852.html
友情链接It题库(ittiku.com)| 版权归yishouce.com所有| 友链等可联系 admin#yishouce.com|粤ICP备16001685号-1