首页 > 网站 > WEB开发 > 正文

JavaScript Patterns 5.3 Private Properties and Methods

2024-04-27 14:22:17
字体:
来源:转载
供稿:网友

javaScript Patterns 5.3 PRivate Properties and Methods

2014-06-25 12:31 by 小郝(Kaibo Hao), ... 阅读, ... 评论, 收藏, 编辑

All object members are public in Javascript.

var myobj = {    myprop : 1,    getProp : function() {        return this.myprop;    }};console.log(myobj.myprop);// `myprop` is publicly accessibleconsole.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 publicconsole.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 privateconsole.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" methodconsole.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]); // truemyarray.isArray({    0: 1}); // falsemyarray.indexOf(["a", "b", "z"], "z"); // 2myarray.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)


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表