asfman
android developer
posts - 90,  comments - 213,  trackbacks - 0

JavaScript 是世界上最被误解的语言。很多人认为它缺乏信息隐藏的特性所以对象不能有私有实例变量和方法。但这是一个误解。JavaScript对象同样可以拥有私有变量。下面就讲解一下:

对象

JavaScript根本上是关于的。数组Array是对象,函数Function是对象,Object就不说了。那什么是对象?对象是名称-值的配对的集合。名称是字符串,值可以是字符串、数字、布尔值和对象(包括数组和函数)。对象常常实现为哈希表以快速存取值。

如果一个值是函数,我们可以将它视为方法method。当调用一个对象的方法时,this 变量就会被设为该对象。这个方法就可以通过this变量访问实例变量。

对象是由构造器constructor产生的,它是初始化对象的函数。构造器提供了其它语言中类提供的特性,包括静态方法和变量。

公共成员

对象的成员都是 public公共成员。任何函数都可以访问、修改或者删除这些成员。有两种主要的途径给新的对象加入成员:

构造器中

这个技术一般用来初始化公共实例变量。构造器的this变量是用来向对象添加成员的。

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

这样,如果我们构造一个新的对象

				var myContainer = new Container('abc');
		

那么myContainer.member 就会包含'abc'

原型中

这个技巧一般用来添加公共方法。当一个成员被检索且没有在对象中发现的时候,那么它就会从对象构造器的 prototype 成员中去获取它。这个原型机制可用来实现继承。它也保存内存。要为一个构造器生成的所有对象加入一个方法,将函数加入构造器的prototype :

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

这样,我们可以调用这个方法

				myContainer.stamp('def')
		

它会返回'abcdef'.

私有成员

私有Private成员要由构造器生成。构造器中的普通的var变量和参数都成为私有成员。

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

这个构造器有三个私有实例变量:param, secret, self。它们被附加到了对象上,但它们无法从外部访问,同时它们也无法被这个对象的公共方法所访问。他们只对私有成员可见。私有方法则是构造器内部的函数。

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

私有方法 dec 检查 secret 实例变量。如果它大于0,就减少 secret 的大小并返回 true 。否则它返回 false 。这个可以限制对象使用三次。

按照惯例,我们给出一个私有的 self 参数。这个可以令对象对私有方法可见。这种做法是因为ECMAScript Language Specification中的一个错误,这个错误令 this 不能正确地对内部函数设置。

私有方法无法被公共方法调用。要令私有方法有用,我们需要引入一种特权方法。

特权成员

一个特权A privileged方法可以访问私有的变量和方法,同时它对公共域可见。也可以删除或替换一个特权方法,但不能改变它。

特权方法是用 this 在构造器中分配的。

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

service 就是一个特权方法。前三次调用会返回'abc'。之后 ,它会返回 nullservice调用的私有的dec 方法,而 dec 又访问了私有的 secret 变量。service 对其它的对象和方法是可见的,但不能直接访问私有成员。

闭包

这种公共、私有和特权成员的模式是可行的原因是由于JavaScriptclosure闭包。这个意味着一个内部的函数总是可以访问这个函数外部的变量和参数,甚至在外部的函数返回之后。这是这个语言的一个极其强大的特性。目前没有哪本关于JavaScript编程的书展示了如何发掘这个特性。大多数都没有提到。

私有和特权成员只能在对象构造的时候生成。公共成员可以在任意时刻添加。

Patterns模式

Public公共

function Constructor (...) {
this. membername = value ;
}
Constructor.prototype.membername = value;

Private私有

function Constructor (...) {
var self = 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.



posted on 2005-04-21 22:46 ShiningRay 阅读(789) 评论(2)  编辑 收藏收藏至365Key 所属分类: JavaScript

What People Are Saying About This Post...

# re: JavaScript中的私有成员 2005-10-18 12:15 南枫
这样实现的私有成员是静态的,与类实例的私有成员还是有差别的.
我也曾经这样模拟私有成员,后来因为它是静态的引发了一个错误,调试了很久才发现,后来就放弃了这种方法,不过构造函数的参数与它内部定义的变量不大一样,我试过,构造函数的参数是附着在类实例上的,所以,如果一定要模拟私有成员变量的话,可以考虑让它们成为类构造的参数(好在JS并不要求参数必须匹配)  回复
  

# re: JavaScript中的私有成员2006-01-12 10:13 DSONet
你说得这个私有成员得静态性是什么概念?
var a=new Container('this eg1;');
var b=new Container('this eg2;');
with(document){
write(a.service());write(a.service());write(a.service());write(a.service());
write(b.service());write(b.service());write(b.service());write(b.service());
};
看看这个,secret分别属于各自得对象实例.  回复
posted on 2006-04-11 08:49 汪杰 阅读(158) 评论(0)  编辑 收藏 引用 所属分类: javascript
只有注册用户登录后才能发表评论。

<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(15)

随笔分类(1)

随笔档案(90)

文章分类(727)

文章档案(712)

相册

收藏夹

http://blog.csdn.net/prodigynonsense

友情链接

最新随笔

搜索

  •  

积分与排名

  • 积分 - 459590
  • 排名 - 6

最新随笔

最新评论

阅读排行榜

评论排行榜