JavaScript中的私有成员

转载 2006年05月21日 16:17:00

JavaScript中的私有成员

Douglas Crockford www.crockford.com

翻译:ShiningRay @ Nirvana Studio

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

对象

JavaScript根本上都是关于的对象(Object)的。数组(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对其它的对象和方法是可见的,但不能直接访问私有成员。

闭包

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

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

模式

公共(Public)

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

私有(Private)

function Constructor(...) {  
	var self =  this;
	var membername =  value;  
	function  membername(...)  {...}
}
注意,实际上函数语句
function  membername(...)  {...}
是以下语句的缩写,两者相同:
var  membername = function  membername(...)  {...};

特权(Privileged)

function Constructor(...) {  
	this.membername =  function (...)  {...};
}
Copyright 2001 Douglas Crockford. All Rights Reserved Wrrrldwide.

C++ 私有成员

类的成员默认为私有,私有成员不能被对象直接访问,只能通过在类中设定的接口函数来访问。在类中设置一个公有的借口函数,类的对象通过接口函数才能访问这个成员。     为什么要这么麻烦地设置私有数据成员,然...
  • moli1949
  • moli1949
  • 2015年11月30日 16:50
  • 597

js私有成员定义和访问

Javascript  根本上是和对象相关的。数组是对象。函数是对象。对象是对象。那什么是 对象呢?对象是名 - 值对的集合。名是字符串,值可以是字符串,数字,布尔值或者对象 ( 包 括数组和函数 )...
  • fyhjuyol
  • fyhjuyol
  • 2015年05月07日 17:53
  • 619

c++中类中私有成员的调用?

Questionclass A { private: int x; public: A() { x = 90; } A(A a1, A a2)...
  • renwotao2009
  • renwotao2009
  • 2016年05月19日 10:26
  • 924

Python类的私有成员

#!/usr/bin/env python #-*- coding:utf8 -*- """ Python中类的成员函数、成员变量默认都是公开的(public), 而且Python中没有类似p...
  • ajaxuser
  • ajaxuser
  • 2012年07月25日 20:21
  • 3182

python 类私有成员

Python中默认的成员函数,成员变量都是公开的(public),而且python中没有类似public,private等关键词来修饰成员函数,成员变量。 在python中定义私有变量只需要在变...
  • mafuli007
  • mafuli007
  • 2012年07月24日 08:01
  • 2317

Java访问类中的私有成员(private member)

一般而言,一个类只允许访问另一个类中的public 然而当我们非要访问私有成员的时候,这时候Java的反射机制就用得上了。package com.comac.reflect; public cla...
  • sinat_36246371
  • sinat_36246371
  • 2016年10月13日 22:36
  • 1139

友元函数 无法访问 类私有成员

#include  02usingnamespacestd;  03classcylinder  04{  05    friendistream operator>>(istream& is,cyl...
  • zz457887107
  • zz457887107
  • 2011年05月27日 07:58
  • 1365

C++中基类私有成员会被继承吗

1.派生类间接访问继承私有成员在类的继承中,类的私有成员在派生类中是“不可见“的,这种”不可见“是指在派生类的成员函数中,或者通过派生类的对象(指针,引用)不能直接访问它们。但是,不能直接访问并不代表...
  • K346K346
  • K346K346
  • 2015年11月05日 00:51
  • 5511

第13周-项目1-基类中成员的访问限定符和派生类的继承方式

In member function 'void StudentB::showB()':| error: 'int StudentA::num' is private| error: within...
  • ning847273990
  • ning847273990
  • 2013年05月28日 19:39
  • 1264

C++ 为什么类的构造函数可以访问类的私有成员?解惑

看下面的例子程序:class Point{public:Point(int xx=0,int yy=0){x=xx;y=yy;}Point(Point &p){x=p.x; //这里访问了p对象的私...
  • wesleyluo
  • wesleyluo
  • 2010年05月20日 08:51
  • 2565
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:JavaScript中的私有成员
举报原因:
原因补充:

(最多只允许输入30个字)