一般的面向对象语言C++或JAVA,对象都是有私有成员的。js中没有类的改变,同样也没有对象的私有成员这个概念。但是可以通过某些特殊写法,模拟出私有成员。

1、特权模式:

  (1)在构造函数内部声明的变量、子函数以及参数,全部都是函数私有的,可以看作私有成员。给this指针添加的闭包,全部都是公有成员

  所以下面例子:参数a/b、变量_value、函数add是私有的,外面无法访问,故c1.add会报错

  setValue和getValue是公有的,c1可以访问

function MyClass(a,b){
//private
var _value=;
function add(){
_value=a+b;
}
//process
add();
//public
this.getValue=function(){
return _value;
}
this.setValue=function(a1,b1){
a=a1;
b=b1;
add();
}
}
var c1=new MyClass(,);
var c2=new MyClass(,);
c1.setValue(,);
alert(c1.getValue());//7
alert(c2.getValue());//3
alert(c1.add());//c1中无add方法,报错c1.add is not a function(…)

  (2)这种模拟方法的优点是代码清晰明了,缺点是每个对象的成员函数,不论是私有还是公有,都是自己独有的即便成员函数的功能相同,但他们却是存放在不同位置的不同函数。
  (3)这种模拟方法只模仿了一个外形。OOP语言中,每个对象的成员函数,在内存中只体现为一个单元,我们违背了这一原则

2、私有作用域模式:

  (1)既然模拟出了块级作用域,可以考虑把块级作用域拿来,模拟一下私有成员。

(function(){
//private
var _value=, _a=, _b=;
function add(){
_value=_a+_b;
}
//construct
MyClass=function(a,b){
_a=a;
_b=b;
add();
}
//public
MyClass.prototype.getValue=function(){
return _value;
}
MyClass.prototype.setValue=function(a1,b1){
_a=a1;
_b=b1;
add();
}
})();
var c1=new MyClass(,);
var c2=new MyClass(,);
c1.setValue(,);
alert(c1.getValue());//7
alert(c2.getValue());//7
alert(c1.add());//报错

  (2)上面例子我们使用了块级作用域_value、_a、_b、add都是匿名函数的私有变量MyClass前面没有var,所有MyClass是全局变量,可以在块级作用域外部使用getValue和setValue是通过原型模式为MyClass添加的公共方法
  (3)这样写,MyClass所有实例的公共方法不再单独创建,而是共享使用;而私有方法,则是共享作用域链中的add,也不是独立创建的。针对成员方法而言,已经与C++和java非常接近了。
  (4)但这样写的缺点也是显而易见的就是私有数据成员_value、_a、_b在各实例之间也是共享的。这些成员,相当于static成员

3、综合模式

(function(){
//private static
var _count=;
function add(a,b){
return a+b;
}
//construct
MyClass=function(a,b){
//private
var _data={ value: }
//process
_data.value=add(a,b);
_count++;
//public
this.data=function(){return _data;}
}
//public
MyClass.prototype.getValue=function(){
return this.data().value;
}
MyClass.prototype.setValue=function(a,b){
this.data().value=add(a,b);
}
MyClass.prototype.getCount=function(){
return _count;
}
})(); var c1=new MyClass(,);
var c2=new MyClass(,);
c1.setValue(,);
alert(c1.getValue());//7
alert(c2.getValue());//3
alert(c1.getCount());//2
alert(c2.getCount());//2

  (1)为了解决私有作用域模式中私有数据成员共享的问题,必须将私有数据成员写在MyClass内。但这样,公有成员函数就不能使用他们了。所以还是要使用一个特权函数,提供私有数据成员的接口,这个是无法避免的,因此只能让代价尽量的小,比如对私有数据成员做一个打包。
  (2)私有方法是内存共享的,比如add函数。然而实际上,私有方法只要共享内存,就是private static状态,而private static状态方法,如果想使用非形参变量时,也只能使用private static的变量,比如_count。想使用实例的私有数据成员,只能通过形参传入。
  (3)公有方法是内存共享的,是通过原型链实现的。公有方法使用私有数据成员,就必须得到私有数据成员的接口。我们做的this.data就是接口
  (4)整个模式中,闭包个数只有一个,就是this.data,这个闭包是无法避免的。

深入理解JavaScript模拟私有成员的更多相关文章

  1. 面向对象的JavaScript(3):私有成员和公开成员

    在小项目中对于JavaScript使用,只要写几个function就行了.但在大型项目中,尤其是在开发追求 良好的用户体验的网站中,如SNS,就会 用到大量的JavaScrpt,有时JavaScrip ...

  2. 深入理解javascript闭包【整理】

    原文链接:http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html 英文原文:http://www.jibb ...

  3. javascript模式(1)--私有成员

    javascript是基于对象的一门语言,没有想java等语言那样子拥有封装的特性.但是javascript可以通过闭包来进行模拟. 1.构造函数与私有成员 可以用构造函数形成一个闭包,实现内部成员的 ...

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

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

  5. [C++参考]私有成员变量的理解

    私有成员变量的概念,在脑海中的现象是,以private关键字声明,是类的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量. 然而,在实现拷贝构造函数和赋值符函数时,在函数里利用对象直接访问了 ...

  6. JavaScript中的私有成员[翻译]

    原作者:Douglas Crockford,原文地址:http://www.crockford.com/javascript/private.html JavaScript 是世界上被误解最深的编程语 ...

  7. 精读JavaScript模式(七),命名空间模式,私有成员与静态成员

    一.前言 惰性十足,这篇2月19号就开始写了,拖到了现在,就是不愿意花时间把看过的东西整理一下,其它的任何事都比写博客要有吸引力,我要反省自己. 从这篇开始,是关于JS对象创建模式的探讨,JS语言简单 ...

  8. Python模拟保护和私有成员

    保护成员:以一个下划线开头.Python不会做特殊处理 私有成员:以两个下划线开头.Python会做mangling

  9. 深入理解javascript(一)

    此段文章摘自大叔的博客: 此文的目的是书写可维护的javascript代码. 最小的全局变量: JavaScript通过函数管理作用域.在函数内部声明的变量只在这个函数内部,函数外面不可用.另一方面, ...

随机推荐

  1. java中常用的String方法

    1 length()字符串的长度 String a = "Hello Word!"; System.out.println(a.length); 输出的结果是字符串长度10. 2 ...

  2. (5) go 控制台输入输出、进制转换、原反补码、位运算

    一.控制台接受输入 二.原反补码 三.位运算 四.移位运算

  3. python笔记四:面向对象

    1.类 class Student(object): def __init__(self, name, score): self.name = name self.score = score 1)__ ...

  4. Trie树【p2264】情书

    Background 一封好的情书需要撰写人全身心的投入.CYY同学看上了可爱的c**想对她表白,但却不知道自己写的情书是否能感动她,现在他带着情书请你来帮助他. Description 为了帮助CY ...

  5. XML--读写操作

    XML文档的相关操作 1.配置文件:在实际项目开发中,XML作为配置文件是不可取代的(框架中的部分功能可以以注解形式来取代) (1) 不同技术,XML配置文件的作用也不一样. (2) 比如当前和这个阶 ...

  6. Minimum Height Trees -- LeetCode

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  7. BZOJ 4027:[HEOI2015]兔子与樱花(贪心+树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4027 [题目大意] 樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1 ...

  8. 【线段树/区间开平方】BZOJ3211-花神游历各国

    [题目大意] 给出一些数,有两种操作.(1)将区间内每一个数开方(2)查询每一段区间的和 [思路] 普通的线段树保留修改+开方优化.可以知道当一个数为0或1时,无论开方几次,答案仍然相同.所以设置fl ...

  9. 【贪心】POJ1328-Radar Installation

    [思路] 以每一座岛屿为圆心,雷达范围为半径作圆,记录下与x轴的左右交点.如果与x轴没交点,则直接退出输出“-1”.以左交点为关键字进行排序,从左到右进行贪心.容易知道,离每一个雷达最远的那一座岛与雷 ...

  10. android系统各种音量的获取与设置

    获取系统音量 通过程序获取android系统手机的铃声和音量.同样,设置铃声和音量的方法也很简单! 设置音量的方法也很简单,AudioManager提供了方法: publicvoidsetStream ...