JavaScript的public、private和privileged模式


Posted in Javascript onDecember 28, 2009

Summary
私有变量 在对象内部使用'var'关键字来声明,而且它只能被私有函数和特权方法访问。
私有函数 在对象的构造函数里声明(或者是通过var functionName=function(){...}来定义),它能被特权函数调用(包括对象的构造函数)和私有函数调用。
特权方法 通过this.methodName=function(){...}来声明而且可能被对象外部的代码调用。它可以使用:this.特权函数() 方式来调用特权函数,使用 :私有函数()方式来调用私有函数。
公共属性 通过this.variableName来定义而且在对象外部是可以读写的。不能被私有函数所调用。
公共方法 通过ClassName.prototype.methodName=function(){...}来定义而且可以从对象外部来调用。
原型属性 通过ClassName.prototype.propertyName=someValue来定义。
静态属性 通过ClassName.propertyName=someValue来定义。
另外注意下这种写法: var 函数名=function 函数名(){...} 这个函数被调用时具有特权函数和私有函数的特性。
例:

<html> 
<head> 
<title></title> 
<script type="text/javascript"> 
function Container( param ) { 
function dec(){ 
if ( secret > 0 ) { 
secret -= 1; 
setSecret( 7) 
alert( secret ); 
return true; 
} 
else { 
// alert( "over"+this.member); 
return false; 
} 
} 
// this.dec = dec; 
//this.dec = function dec (){...} different from above code. 
function setSecret( num ){ 
secret = num; 
} 
this.member = param; 
var secret = 3; 
var self = this; 
this.service = function () { 
if (dec()) { 
alert(); 
} 
else { 
return null; 
} 
} 
} 
// --------------------------------------- 
function start(){ 
alert( "Start" ) 
var test = new Container( 'liuqi' ); 
// test.setSecret( 2 ); 
test.service(); 
test.service(); 
test.service(); 
test.service(); 
var test2 = new Container( 'liuqi' ); 
//test2.service(); 
// Container.dec(); 
} 
</script> 
</head> 
<body> 
<div onclick="start()" style="color:blue">click me</div> 
</body> 
</html>

JavaScript是世界上最被误解的编程语言。有人认为它缺少信息隐藏的特性,因为JavaScript对象不能拥有私有变量的方法。
但是这是个误解。JavaScript对象可以拥有私有成员。
对象
JavaScript从根本上就是关于对象的。数组是对象,方法是对象,Object也是对象。什么是对象?对象就是键值对的集合。键是字符串,
值可以是字符串,数字,布尔和对象(包括数组和方法)。对象通常被实现为Hashtable,这样值就可以被快速获取。
如果值是一个函数,我可以称其为方法。当对象的方法被调用时,“this”变量则被赋予该对象。方法可以通过“this”变量访问实例
变量。
对象可以由初始化对象的方法 -- 构造函数产生。构造函数提供在其他编程语言中类提供的特性,包括静态变量和方法。
Public
对象的成员都是public成员。任何对象都可以访问,修改,删除这些成员或添加新成员。主要有两种方式来在一个新对象里放置成员:
在构造函数里
这种技术通常用来初始化public实例变量。构造函数的“this”变量用来给对象添加成员。
Java代码
functin Container(param) { 
this.member = param; 
} 
functin Container(param) { 
this.member = param; 
}

这样,如果我们构造一个新对象var myContainer = new Container('abc'),则myContainer.member为'abc'。
在prototype里
这种技术通常用来添加public方法。当寻找一个成员并且它不在对象本身里时,则从对象的构造函数的prototype成员里找。
prototype机制用来做继承。为了添加一个方法到构造函数创建的所有对象里,只需添加到构造函数的prototype:
Java代码
Container.prototype.stamp = function (string) { 
return this.member + string; 
} 
Container.prototype.stamp = function (string) { 
return this.member + string; 
}

这样,我们可以调用该方法myContainer.stamp('def'),结果为'abcdef'。
Private
private成员由构造函数产生。普通的var变量和构造函数的参数都称为private成员。
Java代码
function Container(param) { 
this.member = param; 
var secret = 3; 
var that = this; 
} 
function Container(param) { 
this.member = param; 
var secret = 3; 
var that = this; 
}

该构造函数创建了3个private实例变量: param,secret和that。它们被添加到对象中,但是不能被外部访问,也不能被该对象自己的
public方法访问。它们只能由private方法访问。private方法是构造函数的内部方法。
Java代码
function Container(param) { 
function dec() { 
if (secret > 0) { 
secret -= 1; 
return true; 
} else { 
return false; 
} 
} 
this.member = param; 
var secret = 3; 
var that = this; 
} 
function Container(param) { 
function dec() { 
if (secret > 0) { 
secret -= 1; 
return true; 
} else { 
return false; 
} 
} 
this.member = param; 
var secret = 3; 
var that = this; 
}

private方法dec检查secret实例变量。如果它大于0,则减少secret并返回true,否则返回false。它可以用来让这个对象限制用3次。
按照惯例,我们定义一个private的that变量。这用来让private方法可以使用本对象。这样做是因为ECMAScript语言规范有一个错误,
该错误导致不能正确的设置this给内部方法。
private方法不能被public方法调用。为了让private方法有用,我们需要引入privileged方法。
Privileged
privileged方法可以访问private变量和方法,并且它本身可以被public方法和外界访问。可以删除或替代privileged方法,但是不能
更改它或强制它泄露自己的秘密。
privileged方法在构造函数里用this分配。
Java代码
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() { 
if (dec()) { 
return that.member; 
} else { 
return null; 
} 
}; 
} 
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() { 
if (dec()) { 
return that.member; 
} else { 
return null; 
} 
}; 
}

service是privileged方法。前三次调用myContainer.service()将返回'abc'。之后,它将返回null。service调用private的dec方法,
dec方法访问private的secret变量。service对其他对象和方法可见,但是它不允许直接访问private变量。
闭包
由于JavaScript有闭包,public,private和privileged成员的模式是可行的。这意味着一个内部方法始终可以访问它的外部方法的
var变量和参数,甚至在外部方法返回之后。这是JavaScript语言的一个非常强大的特性。当前没有展示如何发掘这种特性的JavaScript
编程书籍,大多数甚至都没提到。
private和privileged成员只能在对象被构造时产生。public成员则可以在任何时候添加。
模式
public
Java代码
function Constructor(...) { 
this.membername = value; 
} 
Constructor.prototype.membername = value; 
function Constructor(...) { 
this.membername = value; 
} 
Constructor.prototype.membername = value;

Private
Java代码
function Constructor(...) { 
var that = this; 
var membername = value; 
function membername(...) {...} 
} 
// 注意: function语句 
// function membername(...) {...} 
// 是如下代码的简写 
// var membername = function membername(...) {...}; 
function Constructor(...) { 
var that = this; 
var membername = value; 
function membername(...) {...} 
} 
// 注意: function语句 
// function membername(...) {...} 
// 是如下代码的简写 
// var membername = function membername(...) {...};

Privileged
Java代码
function Constructor(...) { 
this.membername = function (...) {...}; 
} 
function Constructor(...) { 
this.membername = function (...) {...}; 
}

译者注:我认为可以简单的把privileged方法简单的看成是构造函数里的public方法,因为privileged方法可以被外界和public方法访问,
而它自身又可以访问private变量。
Javascript 相关文章推荐
自己写的Javascript计算时间差函数
Oct 28 Javascript
基于jquery扩展漂亮的CheckBox(自己编写)
Nov 19 Javascript
浅析JS中document对象的一些重要属性
Mar 06 Javascript
js和jquery中循环的退出和继续下一个循环
Sep 03 Javascript
node.js中的buffer.copy方法使用说明
Dec 14 Javascript
JS实现带有3D立体感的银灰色竖排折叠菜单代码
Oct 20 Javascript
jQuery实现简单的网页换肤效果示例
Sep 18 Javascript
Zepto实现密码的隐藏/显示
Apr 07 Javascript
React为 Vue 引入容器组件和展示组件的教程详解
May 03 Javascript
ant-design-vue按需加载的坑的解决
May 14 Javascript
vue 实现click同时传入事件对象和自定义参数
Jan 29 Vue.js
gojs实现蚂蚁线动画效果
Feb 18 Javascript
Javascript 面向对象特性
Dec 28 #Javascript
extJs 常用到的增,删,改,查操作代码
Dec 28 #Javascript
firefox和IE系列的相关区别整理 以备后用
Dec 28 #Javascript
javascript 显示当前系统时间代码
Dec 28 #Javascript
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
Dec 28 #Javascript
javascript options属性集合操作代码
Dec 28 #Javascript
javascript 动态调整图片尺寸实现代码
Dec 28 #Javascript
You might like
用 php 编写的日历
2006/10/09 PHP
php中通过虚代理实现延迟加载的实现代码
2011/06/10 PHP
hadoop中一些常用的命令介绍
2013/06/19 PHP
PHP cdata 处理(详细介绍)
2013/07/05 PHP
PHP简单实现“相关文章推荐”功能的方法
2014/07/19 PHP
WordPress中重置文章循环的rewind_posts()函数讲解
2016/01/11 PHP
thinkPHP交易详情查询功能详解
2016/12/02 PHP
PHP使用file_get_contents发送http请求功能简单示例
2018/04/29 PHP
php微信公众号开发之二级菜单
2018/10/20 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
javascript 保存文件到本地实现方法
2012/11/29 Javascript
javascript设置金额样式转换保留两位小数示例代码
2013/12/04 Javascript
javascript实现多栏闭合展开式广告位菜单效果实例
2015/08/05 Javascript
基于Arcgis for javascript实现百度地图ABCD marker的效果
2015/09/12 Javascript
jQuery+ajax实现滚动到页面底部自动加载图文列表效果(类似图片懒加载)
2016/06/07 Javascript
jQuery模拟Marquee实现无缝滚动效果完整实例
2016/09/29 Javascript
Nodejs下DNS缓存问题浅析
2016/11/16 NodeJs
Bootstrap导航条的使用和理解3
2016/12/14 Javascript
VUE重点问题总结
2018/03/19 Javascript
微信小程序有旋转动画效果的音乐组件实例代码
2018/08/22 Javascript
JavaScript this指向相关原理及实例解析
2020/07/10 Javascript
Python字典操作详细介绍及字典内建方法分享
2018/01/04 Python
APIStar:一个专为Python3设计的API框架
2018/09/26 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
2018/12/11 Python
Python matplotlib画图与中文设置操作实例分析
2019/04/23 Python
Python3中_(下划线)和__(双下划线)的用途和区别
2019/04/26 Python
python通过http下载文件的方法详解
2019/07/26 Python
python批量修改交换机密码的示例
2020/09/22 Python
HTML5超炫酷粒子效果的进度条的实现示例
2019/08/23 HTML / CSS
致200米运动员广播稿
2014/02/06 职场文书
化工操作工岗位职责
2014/04/29 职场文书
群众路线表态发言材料
2014/10/17 职场文书
十七岁的单车观后感
2015/06/12 职场文书
优秀共产党员主要事迹材料
2015/11/05 职场文书
遇事可以测出您的见识与格局
2019/09/16 职场文书
MySQL详解进行JDBC编程与增删改查方法
2022/06/16 MySQL