封装和信息隐藏是面向对象编程语言中的两个重要的概念,我们可以认为两者是同一事物的不同表述,信息隐藏是目的,而封装则是手段。
我们知道,在c++/Java中,有访问修饰符public, protected和private,来对变量或者方法的访问域进行设置,而在JavaScript中,并没有类似的修饰符。因此,我们必须通过模拟的方法来达到这一目的。
在讨论如何模拟private之前,有几个JavaScript的重要概念需要先了解一下: Scope, Nested Functions, Closures
我们先来看一段代码:
function foo() {
var a = 10;
function bar() {
a *= 2;
}
bar();
return a;
}
这段代码里面用到了内部函数的概念,在function foo里面包含了一个bar方法。同时,我们可以看到, a这个变量是在foo方法里面定义的,却可以被bar方法访问,此所谓closure。
如果我们换一种方式调用bar的话:
function foo() {
var a = 10;
function bar() {
a *= 2;
return a;
}
return bar;
}
var baz = foo(); // baz is now a reference to function bar.
baz(); // returns 20.
baz(); // returns 40.
baz(); // returns 80.
var blat = foo(); // blat is another reference to bar.
blat(); // returns 20, because a new copy of a is being used.
我们可以在a的scope以外通过baz方法访问到a,同时又保证了a的封装性,这个就是我们用来模拟面向对象封装的手段。
通过这个例子,我想到一个问题,对于面向对象语言如c++或是java,对象的构造函数都是没有返回值的,而在javascript中,我们没有办法限制构造函数是否返回值,那么当我们用一个有返回值的构造函数时,会出现什么样的情况呢?
function foo() {
var a = 10;
function bar() {
a *= 2;
return a;
}
bar.hello = "hello bar";
return bar;
}
foo.hello = "hello foo";
var baz = new foo();
alert(baz.hello);
打印出来的结果是Hello bar,也就是说,我们事实上创建了一个bar的对象,所以new创建的对象不是构造函数,而是构造函数返回的值。
那么如果构造函数返回的是一个基本类型呢?
function foo() {
var a = 10;
return a;
}
foo.hello = "hello foo";
var baz = new foo();
alert(baz.hello);
alert(baz);
调试结果显示,baz是个空的没有属性的对象,a的值貌似已经丢失。。。
回到我们之前的问题上来, 利用closure,我们便可以创建出具有封装性的类来:
var Book = function(newIsbn, newTitle, newAuthor) { // implements Publication
// Private attributes.
var isbn, title, author;
// Private method.
function checkIsbn(isbn) {
...
}
// Privileged methods.
this.getIsbn = function() {
return isbn;
};
this.setIsbn = function(newIsbn) {
if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');
isbn = newIsbn;
};
this.getTitle = function() {
return title;
};
this.setTitle = function(newTitle) {
title = newTitle || 'No title specified';
};
this.getAuthor = function() {
return author;
};
this.setAuthor = function(newAuthor) {
author = newAuthor || 'No author specified';
};
// Constructor code.
this.setIsbn(newIsbn);
this.setTitle(newTitle);
this.setAuthor(newAuthor);
};
// Public, non-privileged methods.
Book.prototype = {
display: function() {
...
}
};
最终,利用匿名方法,我们还可以创建静态变量以及静态方法:
var Book = (function() {
// Private static attributes.
var numOfBooks = 0;
// Private static method.
function checkIsbn(isbn) {
...
}
// Return the constructor.
return function(newIsbn, newTitle, newAuthor) { // implements Publication
// Private attributes.
var isbn, title, author;
// Privileged methods.
this.getIsbn = function() {
return isbn;
};
this.setIsbn = function(newIsbn) {
if(!checkIsbn(newIsbn)) throw new Error('Book: Invalid ISBN.');
isbn = newIsbn;
};
this.getTitle = function() {
return title;
};
this.setTitle = function(newTitle) {
title = newTitle || 'No title specified';
};
this.getAuthor = function() {
return author;
};
this.setAuthor = function(newAuthor) {
author = newAuthor || 'No author specified';
};
// Constructor code.
numOfBooks++; // Keep track of how many Books have been instantiated
// with the private static attribute.
if(numOfBooks > 50) throw new Error('Book: Only 50 instances of Book can be '
+ 'created.');
this.setIsbn(newIsbn);
this.setTitle(newTitle);
this.setAuthor(newAuthor);
}
})();
// Public static method.
Book.convertToTitleCase = function(inputString) {
...
};
// Public, non-privileged methods.
Book.prototype = {
display: function() {
...
}
};
分享到:
相关推荐
此外,对网络协议、特别是PPP(Point-to-Point Protocol)和GRE(Generic Routing Encapsulation)的基础知识也是必要的,因为PPTP是在这些协议基础上建立的。 总结来说,"pptp-1.7.2.tar.gz"是一个包含了PPTP协议...
1. 文件标题 "OMA-TS-MMS-ENC-V1_3-***-C.pdf" 指明了文档的主要内容涉及OMA(Open Mobile Alliance,开放移动联盟)标准下的多媒体消息服务(Multimedia Messaging Service,MMS)的封装协议(Encapsulation ...
数据封装算法(Data Encapsulation Mechanisms)是一种用于安全传输数据的算法。在非对称加密中,DEM可以用来确保数据传输的安全,使得敏感信息在传输过程中不被窃取或篡改。不同数据封装机制在效率、安全性、实现...
这可能包括类(class)的定义,对象(object)的创建,封装(encapsulation)的概念,以及如何通过类来隐藏数据和实现数据的安全性。此外,还可能涉及继承(inheritance),一个类可以从另一个类派生,继承其属性和...
R1(config-if)#encapsulation ppp R1(config-if)#ppp multilink group 10 2.定义虚接口 multilink,后面跟的数字代表所属的multilink group。 R1(config)#int multilink 10 R1(config-if)#ip add 192.168.1.1 255....
描述中的"IP over AX.25 encapsulation for Linux v2.13.6."进一步揭示了这个项目的内容。IP over AX.25是一种在AX.25( Amateur Radio X.25)网络上实现IP(Internet Protocol)的数据链路层封装技术。AX.25是一种...
Python库`hybrid_rsa_aes-0.2.10-py3-none-any.whl`是一个用于加密和解密数据的工具,它结合了RSA和AES两种加密算法,以提供更安全的数据保护。在这个特定的版本0.2.10中,库是针对Python 3编写的,且适用于任何平台...
Geneve(Generic Network Virtualization Encapsulation)是一种新兴的网络虚拟化标准,旨在提供轻量级、可扩展和高度自定义的解决方案。它允许在多个虚拟网络之间建立隧道,以便在不同层面上实现网络隔离和服务质量...
6. **面向对象编程**:VFP支持面向对象编程,可以创建和使用类(classes),继承(inheritance)、封装(encapsulation)和多态性(polymorphism)等概念也得到了实现。 7. **集成开发环境(IDE)**:VFP自带了一个...
设计模式的概念起源于上世纪90年代初,由Erich Gamma等四位著名设计师共同编写的《设计模式:可复用面向对象软件的基础》(Design Patterns: Elements of Reusable Object-Oriented Software)一书,首次系统化地...
3. **继承**:JavaScript 的继承主要通过原型链实现,一个对象可以将另一个对象作为其原型,从而继承其属性和方法。ES6 中引入的 class 关键字也支持类的继承,通过 extends 关键字。 4. **多态**:JavaScript 的...
- 封装(Encapsulation):隐藏对象的内部细节,只暴露必要的接口。 2. **语法特性**: - 主类(Main Class):程序执行的起点,包含`public static void main(String[] args)`方法。 - 异常处理:使用try-catch...
标题中的"print-gre.rar_tcpdump gre"暗示了我们正在讨论如何使用`tcpdump`工具来捕获并解析GRE(Generic Routing Encapsulation)协议的数据包。GRE是一种网络协议,用于在IP网络上封装各种协议数据包,从而允许...
在面向对象编程中,核心概念包括类(Class)、对象(Object)、封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。这些概念构成了OOP的基础,并且在高级语法中,它们的运用和理解会更加深入和细致...
5. **面向对象编程**:Python是一种支持面向对象编程的语言,包括类(class)的定义、对象(object)的创建以及继承(inheritance)、封装(encapsulation)和多态(polymorphism)等概念。初学者需要理解这些基本的...
3. 封装(Encapsulation):封装是将数据和操作数据的方法绑定在一起,对外只暴露必要的接口,隐藏内部实现细节。在C++中,可以通过访问控制修饰符(`public`、`private`、`protected`)来实现封装,保护数据不被...