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

1、特权模式:

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

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

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

function MyClass(a,b){  //private  var _value=0;  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(1,2);
var c2=new MyClass(1,2);
c1.setValue(3,4);
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=0, _a=0, _b=0;  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(1,2);
var c2=new MyClass(1,2);
c1.setValue(3,4);
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=0;  function add(a,b){  return a+b;  }  //construct  MyClass=function(a,b){  //private  var _data={ value:0 }  //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(1,2);
var c2=new MyClass(1,2);
c1.setValue(3,4);
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 闭包

    简介 Closure 所谓"闭包",指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 闭包是 ECMAScript (Ja ...

  2. JavaScript 私有成员

    Class field declarations for JavaScript(JavaScript 类的字段声明)目前已经进入了 stage-3,其中包含一项 OOP 开发者都很关注的内容:Priv ...

  3. 【JavaScript】JavaScript模拟实现面向对象一张图帮助你深刻理解原型链和原型对象

    文章目录 一.JavaScript模拟面向对象 1.函数是类 2.函数中各种变量的声明 3.关于函数内的this 小结:JavaScript中函数是什么? 4.练习:面向对象思想编写Complex类 ...

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

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

  5. JavaScript中的私有成员

    JavaScript中的私有成员 Douglas Crockford www.crockford.com 翻译:ShiningRay @ Nirvana Studio JavaScript 是世界上最 ...

  6. C++ 私有成员变量的理解

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

  7. 私有成员变量理解的补充

    在设计和实现当前类时,实现拷贝构造函数和赋值构造函数时,甚至在成员函数的内部是可以直接访问当前类的对象(以参数的形式)的私有成员变量的.考虑如下的代码: class Test { public:Tes ...

  8. Javascript中公有成员,私有成员,静态成员

    一.实现类的公有成员: 1) 定义的成员属性和方法能够被任何实例访问,对任何的实例都是公开的,成为公有成员.在javascript中,一般的属性和方法的定义都是公有的,请看下面的例子: functio ...

  9. C++57个入门知识点_17 类的访问权限及C语言模拟类的封装(类的私有权限突破方法:编译期进行权限检查,运行期通过指针修改类的私有成员变量;利用函数指针对结构体中成员变量进行修改;CPU大小尾排列)

    接上篇:C++57个入门知识点_16 类的标准写法(类名.成员变量.成员函数及对象命名规则:成员变量一般为私有,成员函数为公有并暴露给外部使用成员变量:防止类过大,声明写在.h,实现写在.cpp,调用 ...

最新文章

  1. 阿里巴巴JAVA面试真题(三)
  2. java中事务的介绍
  3. Kali Linux 安全渗透教程第一更
  4. 磁盘阵列介绍、进程的查看管理、日志文件的查看分析,systemctl的控制
  5. Windows上搭建Python安装包MySQLdb
  6. 线性表 - 数据结构和算法06
  7. centos7 如何安装部署k8s_如何在centos7上安装FreeIPA的客户端
  8. 信息学奥赛一本通(1092:求出e的值)
  9. 红橙Darren视频笔记 条件查询 删除 更新,数据库结合http做缓存机制(数据库操作)下
  10. MateBook14一个多月的使用体验(开发向)
  11. python写算法快吗_用python写排序算法
  12. 【笔记】解析MP3文件信息
  13. AxureRP7.0基础教程系列 部件详解Text Area 文本段落
  14. feign调用接口返回html,Spring Cloud Feign接口返回流
  15. 项目经理和产品经理的区别
  16. 回文子串、回文子序列相关题目
  17. mysql查询性能测试工具_性能测试之数据库监控分析工具PMM
  18. [转] 串行传输 VS 并行传输
  19. 用jacob为word表格设置边框线
  20. Yii Framework 开发教程(22) UI 组件 Zii组件简介

热门文章

  1. WPF 4 DataGrid 控件(基本功能篇)
  2. js获取服务器响应头信息,js获取HTTP的请求头信息
  3. python简单操作题_Python简单练习题可以一起做做
  4. python笔记总结_python学习笔记总结(1)
  5. Nginx —— nginx负载均衡的详细配置 以及 使用案例详解.
  6. 函数参数 不定参数,和 默认参数
  7. python的Web框架,Django框架中的请求与响应
  8. java-------------华为-----------字符串链接最长路径查询
  9. Numpy、Scipy、matplotlib、scikit-learn等常用学习链接
  10. 154 Find Minimum in Rotated Sorted Array 2