JavaScript Privacy

I know that you can achieve something like “privacy” in JavaScript using closure and immediate function calls.

But what if I need full-featured prototyping? I just don’t know how to have private members in a prototype object. If I used privileged methods, I may have private variables and public methods, but I lose the ability to prototype.

Douglas Crockford "prohibits" the use of dangling ones (by placing an underscore in front of the identifier to indicate that it is not part of the public interface).

But is it bad to use? Since there is no way to make it truly private.

What is your opinion on this? How do you deal with this?

+4
source share
3 answers

At first, you don’t lose the prototyping effect when using the functional inheritance pattern. I just assume that you are talking about the good parts, crockford also introduced a fairly simple and efficient way to have common variables for this template. What basically looks like:

var Human = (function(my, priv) { var my = my || {}, priv = priv || {}; my.privatedata = "foobar"; priv.walk = function() { console.log('walking'); return priv; }; priv.talk = function() { console.log('blah blah'); return priv; }; return priv; }()); var Andy = (function(my, priv) { var my = my || {}, priv = Human(my, priv); priv.SpecialAndyThing = function() { console.log('bloggin at typeofnan.com'); return priv; }; return priv; }()); var myAndy = Andy(); myAndy.talk().SpecialAndyThing(); 

You can even extend this technique to have some super methods. Using critical convention variables, such as underlining or something, is not a bad practice at all. It is confusing because no one knows what is going on there (perhaps this argument fails if you are the only one using the codebase).


However, ECMAscript Edition 5 introduces some goodys to have more "private" members in the prototype chain. . One of the important methods for this is .defineProperty , where you can define a property that is not “shallow”. It will look like this:

 var Human = {}; Object.defineProperty(Human, 'privateStuff', { value: 'secret', enumerable: false }); 

Now, the privateStuff property privateStuff not displayed for an object that inherits the Human prototype chain. In any case, this material requires Javascript 1.8.5 and is only available in modern browsers. See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/defineProperty

+5
source

You may be interested in JavaScript design templates . It discusses the Module pattern.

+1
source

Here is an example of how to enable prototype functions to access private variables in all browsers:

 var Book = (function() { var $ = {}; var Book = function(newFirst, newLast) { // Private variables stored in an object literal. var _ = { author_first : newFirst, author_last : newLast }; // Public privileged method for accessing private variables. this._ = function(key) { if(key === $) return _; throw new Error("The _() function must be called internally."); }; }; // Public accessor method. Book.prototype.getAuthor = function() { var _ = this._($); return _.author_first + " " + _.author_last; }; return Book; })(); var bookA = new Book("Chris", "West"), bookB = new Book("Douglas", "Crockford"); alert(bookA.getAuthor()); alert(bookB.getAuthor()); 

This is the same that I implemented the Color class in jPaq .

+1
source

Source: https://habr.com/ru/post/1341623/


All Articles