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. DataGridView修改HeaderText

    dataGridView_htList为一个 DataGridView(ht为HoverTree的缩写)方法一:dataGridView_htList.Columns["HtAddTime& ...

  2. TextBox禁止复制粘贴和数字验证,小数验证,汉字验证

    验证小数 #region 验证小数 /// <summary> /// 验证小数 /// </summary> /// <param name="sender& ...

  3. Java项目打包部署war文件

    1.选中要打包的项目,右键单击,选择“Export-->WAR File”,在弹出的对话框中选择Destination.Server runtime等选项,点击Finish: 2.可以看到指定目 ...

  4. Scalaz(12)- Monad:再述述flatMap,顺便了解MonadPlus

    在前面的几篇讨论里我们初步对FP有了些少了解:FP嘛,不就是F[A]吗?也是,FP就是在F[]壳子(context)内对程序的状态进行更改,也就是在F壳子(context)内施用一些函数.再直白一点就 ...

  5. Android提升篇系列:adb无法识别MX5等特殊机型

    发现自己Ubuntu系统adb无法识别魅族 mx5机型.操作具体如下(其他机型依然适用): 一.Ubuntu环境 1.查看自己当前设备的idVendor lsusb命令直接查看当前usb设别列表,找到 ...

  6. JavaScript学习(2):对象、集合以及错误处理

    在这篇文章里,我们讨论一下JavaScript中的对象.数组以及错误处理. 1. 对象 对象是JavaScript中的一种基本类型,它内部包含一些属性,我们可以对这些属性进行增删操作. 1.1 属性 ...

  7. html和css的编码规范

    HTML和CSS编码规范内容 一.HTML规范 二.CSS规范 三.注意事项: 四.常用的命名规则 五.CSS样式表文件命名 六.文件命名规则 一.HTML规范: 1.代码规范 页面的第一行添加标准模 ...

  8. C#如何在钉钉开发平台中创建部门

    钉钉是阿里巴巴专为中小企业和团队打造的沟通.协同的多端平台,钉钉开放平台旨在为企业提供更为丰富的办公协同解决方案.通过钉钉开放平台,企业或第三方合作伙伴可以帮助企业快速.低成本的实现高质量的移动微应用 ...

  9. Quartz.NET开源作业调度框架系列(三):IJobExecutionContext 参数传递

    前面写了关于Quartz.NET开源作业调度框架的入门和Cron Trigger , 这次继续这个系列, 这次想讨论一下Quartz.NET中的Job如何通过执行上下文(Execution Conte ...

  10. js一些代码方法

    概要 1.替换json对象中属性值(包括子对象) 2.兼容多个$库写法(zepto与jquery) 3.闭包保持变量的做法 详情 1.替换json对象中属性值(包括子对象) //替换json对象属性值 ...