标签:style java io strong ar 数据 cti 代码 log
1.为什么要封装和信息隐藏
做过编程的朋友们知道“耦合”这个词,其实封装的效果就是为了解耦,让类和类之间没有太多的联系,防止某一天修改某一类的时候,产生“多米骨诺牌效应”。
我们可以把信息隐藏看成目的,把封装看成达到信息隐藏的技术。通过封装就可以把对象的内部数据表现形式和实现细节进行隐藏。就好比你会看电视,但是你不知道电视的内部结构一样。但是在javascript中没有任何内置的机制,所以我们还需做些处理,同样来模仿封装。
2.创建对象的方法
1)最简单的一种方法就是门户大开型对象,用一个函数来作为其构造器。所谓的门户大开就是他的所有的属性和方法都是公开的,相当于我们经常用的关键字“public”。
<span style="font-family:SimSun;font-size:18px;"> <script>
//定义一个book的类,function承担了构造函数的工作
var Book = function (name, title, author) {
this.name = name;//书名
this.title = title;//标题
this.author = author;//作者
}
//实例化一个book1对象
var book1 = new Book("语文");
alert(book1.name);
</script></span>
这是一种最简单的创建对象的方式,但是它还是无法做到隐藏对象内部的信息。想想看我们在其他编程语言中是如何创建对象的呢?
2)vb.net中创建属性对象
<span style="font-family:SimSun;font-size:18px;">'定义一个Book类
Public Class Book
Dim book As String '书名
Dim title As String '标题
Dim author As String '作者
''' <summary>
''' 得到书名
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property GetBook() As String
Get
Return book
End Get
Set(value As String)
book = value
End Set
End Property
''' <summary>
''' 返回title
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property GetTitle() As String
Get
Return title
End Get
Set(value As String)
title = value
End Set
End Property
''' <summary>
''' 获取作者
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Property GetAuthor() As String
Get
Return author
End Get
Set(value As String)
author = value
End Set
End Property
End Class
</span>
3.利用闭包模仿VB.NET构造函数
1)看了上述VB.NET的代码,其实我们也可以在javascript去模仿实现,还是上述的操作,定义一个Book类,关于这个类有三个属性,如果你只想得到的话,可以只简单的设置一个get方法。为了区分私有和公有成员,可以在方法和属性名称前加下划线来区分。
<span style="font-family:SimSun;font-size:18px;"> </span><pre class="javascript" name="code"><span style="font-family:SimSun;font-size:18px;">//定义一个book的类,function承担了构造函数的工作
var Book = function (name) {
this._name = name;//书名
//通过一个内嵌函数,来实现外部的函数能够访问到内部的私有变量
this._GetName = function () {
return this._name;
}
this._SetName = function (value) {
this._name=value
}
}
//实例化一个book1对象
var book1 = new Book("语文");
alert(book1._GetName());//正确
book1._SetName("数学");
alert(book1._GetName());//正确
alert(_name);//错误操作
alert("");
</span><span style="font-family:SimSun;font-size:18px;">这就是一个简单的闭包,通过内嵌函数来返回外层函数的私有变量,从而即封装了内部函数的私有变量又可以访问的到。有关于闭包的知识,可以看我先前的博客。</span>
2)以上的操作还可以通过原型对象的操作来实现。
<span style="font-family:SimSun;font-size:18px;"><script>
//定义一个book的类,function承担了构造函数的工作
var Book = function (name) {
this._name = name;//书名
//通过一个内嵌函数,来实现外部的函数能够访问到内部的私有变量
}
//通过原型对象来设置访问对象的私有属性
Book.prototype = {
_GetName: function () {
return this._name;
},
_SetName: function (value) {
this._name = value;
}
}
//实例化一个book1对象
var book1 = new Book("语文");
alert(book1._GetName());//正确
book1._SetName("数学");
alert(book1._GetName());//正确
alert(_name);//错误操作
alert("");
</script></span>
3)两种方法对比
可以看到通过上述两种操作都可以封装任何对象的私有属性,话又说回来,这两种操作又有什么不同呢?
这就涉及到有关原型对象的知识,本节只是单纯的实现如何封装隐藏信息,不会在展开讨论。至于把所有的方法都创建到原型对象中,就会不管生成对少对象实例,这些方法在内存中只会存在一份,方法都共用,而另一个则不同,没生成一个对象,没调用一个方法,都会占用一份内存。比如说上述的例子中创建了5个Book对象。用例子一中的_GetName方法的话,每个对象都会占用一份内存,而用原型对象创建的话,五个Book对象共用一份内存,这就是他们最本质的区别。
如果用原型对象创建的方法,在实例化Book1的时候,执行方法时,先从本对象开始寻找,如果找到则停止,未找到则会转移到原型对象方法中寻找,这也是为何创建的对象可以共享原型对象方法的本质。
demo
function Person(name, sex) {
this.name = name;
this.sex = sex;
}
Person.prototype.age = 20;
var zhang = new Person("ZhangSan", "man");
console.log(zhang.age); // 20
// 覆盖prototype中的age属性
zhang.age = 19;
console.log(zhang.age); // 19
delete zhang.age;
// 在删除实例属性age后,此属性值又从prototype中获取
console.log(zhang.age); // 20
4.小结
以上就是在javascript中模仿构造函数创建对象的方法,其实与其他语言对比来说,非常的简单。只不过涉及到了一些“闭包”的知识,如果用过其他语言的话,那么你就会非常掌握的。
《javascript设计模式》读书笔记二(封装和隐藏信息)
标签:style java io strong ar 数据 cti 代码 log
原文地址:http://blog.csdn.net/luckyzhoustar/article/details/38794433