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"); // myarray.inArray(["a", "b", "z"], "z"); //

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"); //

References: 

JavaScript Patterns - by Stoyan Stefanov (O`Reilly)

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

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

  2. JavaScript Patterns 5.4 Module Pattern

    MYAPP.namespace('MYAPP.utilities.array'); MYAPP.utilities.array = (function () { // dependencies var ...

  3. JavaScript Patterns 6.7 Borrowing Methods

    Scenario You want to use just the methods you like, without inheriting all the other methods that yo ...

  4. JavaScript Patterns 6.5 Inheritance by Copying Properties

    Shallow copy pattern function extend(parent, child) { var i; child = child || {}; for (i in parent) ...

  5. JavaScript Patterns 7.1 Singleton

    7.1 Singleton The idea of the singleton pattern is to have only one instance of a specific class. Th ...

  6. OOP in JS Public/Private Variables and Methods

    Summary private variables are declared with the 'var' keyword inside the object, and can only be acc ...

  7. JavaScript Patterns 6.6 Mix-ins

    Loop through arguments and copy every property of every object passed to the function. And the resul ...

  8. JavaScript Patterns 6.4 Prototypal Inheritance

    No classes involved; Objects inherit from other objects. Use an empty temporary constructor function ...

  9. JavaScript Patterns 6.3 Klass

    Commonalities • There’s a convention on how to name a method, which is to be considered the construc ...

随机推荐

  1. net发布的dll方法和类显示注释信息(字段说明信息)[图解]

    自己发布的dll添加的另一个项目中突然没有字段说明信息了,给使用带来了很多的不便,原因是为了跨项目引用,所以导致不显示注释信息的,一下是解决这个问题的方法. 在要发布(被引用)的项目上右键 => ...

  2. 用Supervisord管理Python进程

    http://feilong.me/2011/03/monitor-processes-with-supervisord Supervisord是用Python实现的一款非常实用的进程管理工具,类似于 ...

  3. [工具] GIF 动画每帧合并到一张 PNG

    功能:将 GIF 动画每帧合并到一张 PNG 需求:配合 ImageMagick 图像处理软件. 下载:[工具]Gif2Png_Aone_1.0.0.zip 使用方法: 请到 ImageMagick  ...

  4. 【C语言学习趣事】_32_平胸的尴尬,嫁不出去的姑娘

    为什么写这篇文章呢? 为什么要弄这么个题目呢? 首先解释为什么用这个题目.这一切都要从那天在QQ群中的讨论说起,那天在群中,一个哥们问了一个关于(void)0 的问题.然后大家说到了 (void)0和 ...

  5. WebDriver多线程并发

    要想多线程并发的运行WebDriver,必须同时满足2个条件,首先你的测试程序是多线程,其次需要用到Selenium Server.下载位置如下图: 下载下来后是一个jar包,需要在命令行中运行.里面 ...

  6. easyui datagrid 分页略解

    easyui datagrid 本身自带了分页功能. 但是这个需要你自己控制. 在后台可以得到两个datagrid的参数,rows 和page.其中rows是每页要显示的个数,page是第几页.单纯的 ...

  7. 使用coding、daocloud和docker打造markdown纯静态博客

    说起独立博客的技术演变,从数据库到纯文本放git是一大进步,从HTML到markdown又是一大进步. 解析技术有没有进步呢?既然markdown是纯文本了,再用PHP/Python/Ruby去实时解 ...

  8. 用css计算选中的复选框有几个

    上代码: <!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <title>计数< ...

  9. Photoshop如何实现UI自动切图?

    切图严格来说并不是UI设计师的工作, 而是前端工程师的工作,指的是将UI设计师的设计(大部分为photoshop创建的PSD文件)转化为界面(网页或窗体等)所需要资源的过程.切图是衔接UI设计和应用程 ...

  10. browser.html – HTML 实现 Firefox UI

    browser.html 是一个实验性的项目,用于证明一个概念:使用 HTML 重新实现 Firefox UI ,并作为一个应用程序.它是基于浏览器的 API ,并以浏览器的方式和系统的应用工作.即使 ...