《javascript设计模式》读书笔记二(封装和隐藏信息)

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中模仿构造函数创建对象的方法,其实与其他语言对比来说,非常的简单。只不过涉及到了一些“闭包”的知识,如果用过其他语言的话,那么你就会非常掌握的。

时间: 08-27

《javascript设计模式》读书笔记二(封装和隐藏信息)的相关文章

JavaScript设计模式:读书笔记(未完)

该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/3/30: 模式是一种可复用的解决方案,可用于解决软件设计中遇到的常见问题./将解决问题的方法制作成模板,并且这些模板可应用于多种不同的情况.有效模式的附加要求:适合性,实用性,适用性. 模式的优点: 防止局部问题引起大问题,模式让我们的代码更有组织性 模式通常是通用的解决方式,不管我们开发哪种应用程序,都可以用模式优化我们代码的结构 模式确实可以让我们避免代码复用,使代码更

《Javascript设计模式》笔记二 接口

在Javascript当中模仿接口的方法有三种:注释法,属性检查法和鸭式变形法.三者结合令人满意. 1.注释法 /* interface Composite{ function add(child){}; function remove(child){}; function getChild(index){}; } interface FormItem{ function save(){} } */ //用注释法模仿接口 var Com = function(id,method,action){

《JavaScript 高级程序设计》读书笔记二 使用JavaScript

一   <script>元素 a.四个属性: async:立即异步加载外部脚本: defer:延迟到文档完全被解析再加载外部脚本: src:外部脚本路径: type:脚本语言的内容类型: 二   XHTML中用法 a. //<![CDATA[ javascript代码 //]]> 三   <noscript>元素 <JavaScript 高级程序设计>读书笔记二 使用JavaScript

《How Tomcat Works》读书笔记(二)

<How Tomcat Works>读书笔记(二) 这是<How Tomcat Works>第一二章的读书笔记.第一张主要写了一个静态资源处理的web服务器,第二章加了对servlet的处理. 1. 概述 1.1 架构 HttpServer:表示Http服务器,与客户端通信,处理Http请求. StaticResourceProcessor:对静态资源请求进行处理. ServletProcessor:对Servlet资源请求进行处理. Request:表示Http请求,实现了Ser

代码的未来读书笔记&lt;二&gt;

代码的未来读书笔记<二> 3.1语言的设计 对Ruby JavaScript Java Go 从服务端客户端以及静态动态这2个角度进行了对比. 这四种语言由于不同的设计方针,产生了不同的设计风格. Header 客户端 服务端 动态 Html5 Ruby 静态 Java Go 静态动态 静态:无需实际运行,仅根据程序代码就能确定结果. 动态:只有到了运行时才能确定结果.不过无论任何程序,或多或少都包含的动态的特性. 动态运行模式 运行中的程序能识别自身,并对自身进行操作.对程序自身进行操作的编

《Programming in Lua 3》读书笔记(二十一)

日期:2014.8.1 PartⅣ The C API 25 An Overview of the C API Lua是一种嵌入式语言.这就意味着Lua不是单独存在的,而是可以通过一系列的标准库将lua的特性嵌入至其他应用模块中. Lua以Lua interpreter(lua的解释器?)来解决了其不是独立程序,我们直到现在却又能独立使用Lua的问题.这个解释器是一个小型的程序(不超过500行代码),使用lua的标准库来实现独立解释程序,这个程序将处理与用户的交互等操作交给lua的标准库,这些库

大话设计模式读书笔记1——简单工厂模式

最近几日,重温了一下<大话设计模式>这本书,当时读的仓促,有很多没有注意的地方,现在仔细翻看起来,发现这值得细细品味的一本书!! 好东西就要记下来!!! 第一章笔记:从一个简单的计算器程序来看简单工厂模式. 变化的地方就要封装,用一个单独的类来做创造实例的过程这就是工厂. UML图: /// <summary> /// 运算类 /// </summary> public class Operation { public double Number1 { get; set

《编写可维护的javascript》读书笔记(中)——编程实践

上篇读书笔记系列之:<编写可维护的javascript>读书笔记(上) 上篇说的是编程风格,记录的都是最重要的点,不讲废话,写的比较简洁,而本篇将加入一些实例,因为那样比较容易说明问题. 二.编程实践 1.UI松耦合 第一.将css从javascript中抽离(要改变dom样式数据,应该去操作dom的class名而非dom的style属性,后续要修改此样式只需到对应的css文件中修改而不用修改js文件): 第二.将javascript从HTML中抽离,比如下面的写法是不好的 <!-- 不

《卓有成效的程序员》----读书笔记二

六大方面对比Launchy和TypeAndRun(TAR) 对于快速启动工具,很多人都有自己的偏好,多次听到朋友介绍Launchy的好,虽然自己一直在使用着TAR,还是克制不住对于好软件的渴求,下载Launchy进行试用.很多软件都是有一个试用期的,也许新的软件确实不错,但是你习惯了以前使用的那个软件.今天就比较客观的将Launchy和TAR进行一下对比,从界面.上手速度到功能.自定义,以及软件的稳定性.占用资源进行详细的比较. [界面美观]Launchy:毫无疑问这是它的强项.1.0正式版自带

《Programming in Lua 3》读书笔记(二十二)

日期:2014.8.6 PartⅣ The C API 26 Extending Your Application 使用Lua很重要的一点是用来做配置语言.配合主语言做一些功能的配置. 26.1 The Basics 有的时候程序需要配置一些功能信息,很多时候可能有许多别的方法比用lua做配置要更简单:如使用环境变量或者读取文件,读取文件涉及到文件的解析.如果使用Lua进行配置的话,相当于用lua文件替代了要读取的如csv.txt文件等. 使用Lua进行配置的时候,就需要使用Lua API去控制