Private Members in JavaScript

Douglas Crockford
www.crockford.com

JavaScript is the
world's most misunderstood programming language
. Some believe
that it lacks the property of information hiding because
objects cannot have private instance variables and methods. But this
is a misunderstanding. JavaScript objects can have private members.
Here's how.

Objects

JavaScript is fundamentally about objects. Arrays are
objects. Functions are objects. Objects are objects. So what are
objects? Objects are collections of name-value pairs. The names are
strings, and the values are strings, numbers, booleans, and objects
(including arrays and functions). Objects are usually implemented as
hashtables so values can be retrieved quickly.

If a value is a function, we can consider it a method. When
a method of an object is invoked, the this variable is set
to the object. The method can then access the instance variables
through the this variable.

Objects can be produced by constructors, which are
functions which initialize objects. Constructors provide the features
that classes provide in other languages, including static variables
and methods.

Public

The members of an object are all public members. Any
function can access, modify, or delete those members, or add new
members. There are two main ways of putting members in a new
object:

In the constructor

This technique is usually used to initialize public instance
variables. The constructor's this variable is used to add
members to the object.

function Container(param) {
this.member = param;
}

So, if we construct a new object

var myContainer = new Container('abc');

then myContainer.member contains 'abc'.

In the prototype

This technique is usually used to add public methods. When a member is sought and it isn't found in the object itself, then it is taken from the object's constructor's prototype member. The prototype mechanism is used for inheritance. It also conserves memory. To add a method to all objects made by a constructor, add a function to the constructor's prototype:

Container.prototype.stamp = function (string) {
return this.member + string;
}

So, we can invoke the method

myContainer.stamp('def')

which produces 'abcdef'.

Private

Private members are made by the constructor. Ordinary vars and parameters of the constructor becomes the private members.

function Container(param) {
this.member = param;
var secret = 3;
var that = this;
}

This constructor makes three private instance variables: param, secret, and that. They are attached to the object, but they are not accessible to the outside, nor are they accessible to the object's own public methods. They are accessible to private methods. Private methods are inner functions of the constructor.

function Container(param) {

    function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
} this.member = param;
var secret = 3;
var that = this;
}

The private method dec examines the secret instance variable. If it is greater than zero, it decrements secret and returns true. Otherwise it returns false. It can be used to make this object limited to three uses.

By convention, we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.

Private methods cannot be called by public methods. To make private methods useful, we need to introduce a privileged method.

Privileged

A privileged method is able to access the private variables and methods, and is itself accessible to the public methods and the outside. It is possible to delete or replace a privileged method, but it is not possible to alter it, or to force it to give up its secrets.

Privileged methods are assigned with this within the constructor.

function Container(param) {

    function dec() {
if (secret > 0) {
secret -= 1;
return true;
} else {
return false;
}
} this.member = param;
var secret = 3;
var that = this; this.service = function () {
return dec() ? that.member : null;
};
}

service is a privileged method. Calling myContainer.service() will return 'abc' the first three times it is called. After that, it will return null. service calls the private dec method which accesses the private secret variable. service is available to other objects and methods, but it does not allow direct access to the private members.

Closures

This pattern of public, private, and privileged members is possible because JavaScript has closures. What this means is that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned. This is an extremely powerful property of the language. There is no book currently available on JavaScript programming that shows how to exploit it. Most don't even mention it.

Private and privileged members can only be made when an object is constructed. Public members can be added at any time.

Patterns

Public

function Constructor(...) {

this.membername = value;

}
Constructor.prototype.membername =
value;

Private

function Constructor(...)
{

var that = this;
var
membername = value;

function membername(...) {...}

}

Note: The function statement

function
membername(...) {...}

is shorthand for

var membername = function membername(...)
{
...};

Privileged

function Constructor(...)
{

this.membername = function (...) {...};

}

Copyright 2001 Douglas
Crockford.
All
Rights Reserved Wrrrldwide.

Private Members in JavaScript的更多相关文章

  1. Use Private Members from Base Class

    最近看了一段代码:在导出类中调用继承自基类的某个public函数,该函数中对基类中的private数据成员 进行了赋值并将结果打印.看到程序的运行结果后,顿时感觉自己之前(我之前的理解这里就不说明了) ...

  2. js基础知识温习:Javascript中如何模拟私有方法

    本文涉及的主题虽然很基础,在很多人眼里属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题.这里会涉及到对象属性的封装.原型.构造函数.闭包以及立即执行表达式等知识. 公有方法 公有方法 ...

  3. 全面理解面向对象的 JavaScript (share)

     以下分享自:  http://www.ibm.com/developerworks/cn/web/1304_zengyz_jsoo/   简介: JavaScript 函数式脚本语言特性以及其看似随 ...

  4. 全面理解面向对象的 JavaScript

    前言 当今 JavaScript 大行其道,各种应用对其依赖日深.web 程序员已逐渐习惯使用各种优秀的 JavaScript 框架快速开发 Web 应用,从而忽略了对原生 JavaScript 的学 ...

  5. 【JavaScript】Registering JavaScript object methods as callbacks

    The registration of callback functions is very common in JavaScript web programming, for example to ...

  6. [转]JavaScript Namespaces and Modules

    Namespaces In most programming languages we know the concept of namespaces (or packages).Namespaces ...

  7. 摘抄--全面理解面向对象的 JavaScript

    全面理解面向对象的 JavaScript JavaScript 函数式脚本语言特性以及其看似随意的编写风格,导致长期以来人们对这一门语言的误解,即认为 JavaScript 不是一门面向对象的语言,或 ...

  8. 通过示例学习JavaScript闭包

    译者按: 在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包(Closure),这篇博客将提供一些代码示例,帮助大家理解闭包. 原文: JavaScript Closures for Dummi ...

  9. 全面理解面向对象的JavaScript

    转载:http://justcoding.iteye.com/blog/2019293 原文:http://www.ibm.com/developerworks/cn/web/1304_zengyz_ ...

随机推荐

  1. uva 10125 - Sumsets

    题意: 输入n,然后输入n个数字,,要在这n个数字中找出a,b,c,d..满足a,b,c,d是不同元素,并且a + b + c = d...求出最大的d 直接暴力时间复杂度为O(n^4)..会超时.. ...

  2. html+css布局小练习w3cfuns

    虽然花了很长时间,但是也知道了不少,这次也不像以前了,不知道怎么下手,虽然是照着图片做,不过也做出来了图片来自w3cfuns:网站图片url  看了w3cfuns的两天驾驭DIV+CSS 这个网站对新 ...

  3. JS/CSS/IMG加载顺序关系之DOMContentLoaded事件

    DOMContentLoaded介绍 DOMContentLoaded事件的触发条件是: 将会在“所有的DOM全部加载完毕并且JS加载执行后触发”. 但如果“js是通过动态加载进来的话,是不会影响到D ...

  4. word2vec的艰难成长史

    1.首先在网站上面下载gensim,我是在11服务器上面下载的 2.使用winpython打开 3.在command windows 下使用pip install gensim这句话进行,原先使用这句 ...

  5. Ubuntu12.04 下svn服务搭建及Windows客户端tortoisesvn的使用

    在Ubuntu服务端搭建apache+svn 在客户端使用Tortoisesvn工具. 第一步 安装SVN $sudo apt-get install subversion 安装成功后系统会自动建立一 ...

  6. 手绘经典QQ头像 请让我一个人呆一会

                                    

  7. Codeforces 219D Choosing Capital for Treeland

    http://codeforces.com/problemset/problem/219/D 题目大意: 给出一棵树,但是它的边是有向边,选择一个城市,问最少调整多少条边的方向能使一个选中城市可以到达 ...

  8. 【转】win7+ubuntu双系统安装方法--不错

    原文网址:http://blog.csdn.net/lvanneo/article/details/16885121 前段时间又安装一下win7+ubuntu双系统,过段时间就会忘记,这次自己写下来, ...

  9. Putty server refused our key的解决方法

    在使用putty工具使用密钥远程登陆CentOS系统时,出现Putty server refused our key提示,解决办法: 1.查看是否关掉SELINUX. 相关命令:getenforce, ...

  10. Codeforce 218 div2

    D 一开始想错了,试图用"前缀和-容量"来求从上层流下来了多少水",但这是错的,因为溢出可能发生在中间. 然后发现对于每层,溢出事件只会发生一次,所以可以用类似并查集的办 ...