深入理解JavaScript模拟私有成员
一般的面向对象语言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模拟私有成员的更多相关文章
- 面向对象的JavaScript(3):私有成员和公开成员
在小项目中对于JavaScript使用,只要写几个function就行了.但在大型项目中,尤其是在开发追求 良好的用户体验的网站中,如SNS,就会 用到大量的JavaScrpt,有时JavaScrip ...
- 深入理解javascript闭包【整理】
原文链接:http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html 英文原文:http://www.jibb ...
- javascript模式(1)--私有成员
javascript是基于对象的一门语言,没有想java等语言那样子拥有封装的特性.但是javascript可以通过闭包来进行模拟. 1.构造函数与私有成员 可以用构造函数形成一个闭包,实现内部成员的 ...
- js基础知识温习:Javascript中如何模拟私有方法
本文涉及的主题虽然很基础,在很多人眼里属于小伎俩,但在JavaScript基础知识中属于一个综合性的话题.这里会涉及到对象属性的封装.原型.构造函数.闭包以及立即执行表达式等知识. 公有方法 公有方法 ...
- [C++参考]私有成员变量的理解
私有成员变量的概念,在脑海中的现象是,以private关键字声明,是类的实现部分,不对外公开,不能在对象外部访问对象的私有成员变量. 然而,在实现拷贝构造函数和赋值符函数时,在函数里利用对象直接访问了 ...
- JavaScript中的私有成员[翻译]
原作者:Douglas Crockford,原文地址:http://www.crockford.com/javascript/private.html JavaScript 是世界上被误解最深的编程语 ...
- 精读JavaScript模式(七),命名空间模式,私有成员与静态成员
一.前言 惰性十足,这篇2月19号就开始写了,拖到了现在,就是不愿意花时间把看过的东西整理一下,其它的任何事都比写博客要有吸引力,我要反省自己. 从这篇开始,是关于JS对象创建模式的探讨,JS语言简单 ...
- Python模拟保护和私有成员
保护成员:以一个下划线开头.Python不会做特殊处理 私有成员:以两个下划线开头.Python会做mangling
- 深入理解javascript(一)
此段文章摘自大叔的博客: 此文的目的是书写可维护的javascript代码. 最小的全局变量: JavaScript通过函数管理作用域.在函数内部声明的变量只在这个函数内部,函数外面不可用.另一方面, ...
随机推荐
- 无法使用命令 /usr/bin/xdpyinfo 自动检查显示器颜色。请检查是否设置了 DISPLAY
https://blog.csdn.net/woshigedahaoren/article/details/9493887
- AC日记——[ZJOI2012]网络 bzoj 2816
2816 思路: 多个LCT: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 10005 #define l ...
- shell脚本学习(三)
shell echo命令 显示普通字符串: echo "I am cat_crazy.'" 注:这里的双引号可以省略 显示转义字符: 如果要输出引号,*号等需要转义才能输出,如下 ...
- js前端分享功能
直接添加网页分享代码就可以了.实现方法如下:1.打开百度分享:http://share.baidu.com.2.点击“代码获取”.3.进行个性化设置.
- Sqli-labs less 12
Less-12 本关和less11是类似的,只是在id 的参数的处理上有一定的不同 当输入username:admin" Password: (随便) 报错后的结果为: You have a ...
- linux——(1)初识linux
linux有窗口管理员环境和纯文本界面环境,同时linux默认提供6个Terminal来让用户登录.crtl+alt+F1-6可自由切换.其中如果窗口管理员环境处于运行状态,那么可以按crtl+alt ...
- Python开发基础-Day22反射、面向对象进阶
isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象,如果是返回True class Foo ...
- 【BZOJ 3669】 3669: [Noi2014]魔法森林 (动态spfa)
3669: [Noi2014]魔法森林 Description 为了得到书法大家的真传,小E同学下定决心去拜访住在魔法森林中的隐士.魔法森林可以被看成一个包含个N节点M条边的无向图,节点标号为1..N ...
- JavaScript的程序构成
JavaScript的程序构成主要从以下几方面做个总结:控制语句.函数 .事件驱动及事件处理,希望对读者有些帮助. 控制语句: if条件语句 基本格式 if(表述式) 语句段1: ...... els ...
- 【贪心】【后缀自动机】XIII Open Championship of Y.Kupala Grodno SU Grodno, Saturday, April 29, 2017 Problem E. Enter the Word
题意:给你一个串,让你从左到右构造这个串,一次操作可以直接在当前串后面添加一个任意字符,或者拷贝当前串的任意一个子串到当前串的后面.问你最少要多少次操作才能构造出这个串. 从前向后贪心,从当前已构造的 ...