惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Security Blog
Microsoft Security Blog
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Last Week in AI
Last Week in AI
罗磊的独立博客
腾讯CDC
云风的 BLOG
云风的 BLOG
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
U
Unit 42
I
InfoQ
D
DataBreaches.Net
Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
V
V2EX
美团技术团队
IT之家
IT之家
Stack Overflow Blog
Stack Overflow Blog
F
Fortinet All Blogs
GbyAI
GbyAI
S
SegmentFault 最新的问题

博客园 - aming

.Net线程 浅析C# new和override的区别 收集一些.NET开发资源站点和部分优 秀.NET开源项目 (转) 你必须知道的.net C#正则表达式整理备忘 ORACLE 基础 asp.net cache 深入认识javascript中的eval函数 FCKEditor的使用及配置方法 个人总结 javascript跨域问题 Javascript的IE和Firefox兼容问题 typeof、instanceof、constructor与对象类型 javascript内存泄漏问题 JavaScript 中的内存泄露模式 jQuery Ajax 全解析 悟透JavaScript (转) JavaScript的9个陷阱及评点 全面理解javascript的caller,callee,call,apply概念(修改版)
JavaScript的私有变量
aming · 2008-10-27 · via 博客园 - aming

JavaScript,不能创建私有变量?不会吧!

摘至:JavaScript中的私有成员
原文:Private Members in JavaScript


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’。
之后 ,它会返回 null。service调用的私有的 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 (…)  {…};
}