JavaScript Patterns 5.3 Private Properties and Methods

All object members are public in JavaScript.

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

  1. 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.

  1. 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 Patterns 5.3 Private Properties and Methods,布布扣,bubuko.com

时间: 2024-10-12 22:59:07

JavaScript Patterns 5.3 Private Properties and Methods的相关文章

JavaScript Patterns 4.8 Function Properties - A Memoization Pattern

Gets a length property containing the number of arguments the function expects: function func(a, b, c) {} console.log(func.length); // 3 var myFunc = function () { // serialize the arguments object as a JSON string and use that string as a key in you

JavaScript Patterns 5.4 Module Pattern

MYAPP.namespace('MYAPP.utilities.array'); MYAPP.utilities.array = (function () { // dependencies var uobj = MYAPP.utilities.object, ulang = MYAPP.utilities.lang, // private properties array_string = "[object Array]", ops = Object.prototype.toStr

JavaScript Patterns 6.5 Inheritance by Copying Properties

Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) { if (parent.hasOwnProperty(i)) { child[i] = parent[i]; } } return child; } Deep copy pattern function extendDeep(parent, child) { var i, toStr = Obje

JavaScript Patterns 6.7 Borrowing Methods

Scenario You want to use just the methods you like, without inheriting all the other methods that you’ll never need. This is possible with the borrowing methods pattern, which benefits from the function methods  call() and apply(). // call() example

JavaScript Patterns 2.10 Naming Conventions

1. Capitalizing Constructors var adam = new Person(); 2. Separating Words camel case - type the words in lowercase, only capitalizing the first letter in each word. upper camel case, as in  MyConstructor(), lower  camel  case,  as  in  myFunction(),

JavaScript Patterns 7.1 Singleton

7.1 Singleton The idea of the singleton pattern is to have only one instance of a specific class. This means that the second time you use the same class to create a new object, you should get the same object that was created the first time. var obj =

JavaScript Patterns 2.12 Writing API Docs

Free and open source tools for doc generation: the JSDoc Toolkit (http://code.google.com/p/jsdoc-toolkit/) and YUIDoc (http://yuilibrary.com/projects/yuidoc). Process of generating API documentation ? Writing specially formatted code blocks ? Running

JavaScript Patterns 3.2 Custom Constructor Functions

When you invoke the constructor function with new, the following happens inside the function: ? An empty object is created and referenced by this variable, inheriting the prototype of the function. ? Properties and methods are added to the object ref

JavaScript Patterns 2.5 (Not) Augmenting Build-in Prototypes

Disadvantage Other developers using your code will probably expect the built-in JavaScript methods to work consistently and will not expect your additions. Properties you add to the prototype may show up in loops that don't use hasOwnProperty(), so t