JavaScript 封装设计模式介绍

如何在Javascript中利用封装这个特性
服务器君一共花费了155.175 ms进行了4次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议

对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,那么如何在Javascript中利用封装这个特性呢?

我们会把现实中的一些事物抽象成一个Class并且把事物的属性(名词)作为Class的Property把事物的动作(动词)作为Class的methods。在面向对象的语言中(C#等)都会有一些关键字来修饰类或者属性(Private,public,protect),这些关键词描述了访问的权限,不多做解释。

我们来看看Javascript的易变的特性(我们还用上一次的例子):

	var Man = function (name, age) {
             this.Name = name;
             this.Age = age;
       }
      var Person = new Interface("Person", ["GetName", "GetAge"]);
            Man.prototype = { GetName: function () { return this.Name; },
            GetAge: function () { return this.Age; }
        }     
      var Gonn = new Man("Gonn", 25);
      alert(Gonn.GetAge());
    Gonn.DisplayAll = function () { return "Name: "+this.GetName() + "; Age: " + this.GetAge() }
   alert(Gonn.DisplayAll());

先创建了一个Class(Javascript的匿名方法)拥有2个公共的(public)的字段(本篇blog会详细讲解,继续往下看)和2个public的方法,我们创建了一个Instance--Gonn,但是我可以为这个Instance动态的添加一个DisplayAll的方法,我想任何面向对象的语言是做不到这一点的,Javascript的灵活体现之一。

现在假设一个场景,如果有很多的程序员要用这段代码,由于Javascript的易变性,程序员就可以在实例化后改变Name的值,那初始化的动作就没有意义了:

	var Gonn = new Man("Gonn", 25);
	Gonn.Name = "Alice";
	alert(Gonn.GetName());

所以我们不能让外部的人去任意的修改这个字段,在Java或C#中我们只需要个这个字段改为Private,就万事OK了,但是Javascript没有这个关键词,那我们需要这么做呢。我们可以想下在C#除了设置Private之外我们还可以怎么做?我们可以设置Setter和Getter方法。

我们来修改下上面的代码:我们称方法一:

 var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge"]);
        var Man = function (name, age) {
            this.SetAge(age);
            this.SetName(name);
        }
        Man.prototype = {
            SetName: function (name) { this.Name = name; },
            SetAge: function (age) { this.Age = age; },
            GetName: function () { return this.Name; },
            GetAge: function () { return this.Age; }
        }
       var Alan = new Man("Alan", 25);
       Alan.Name = "Alice"; //悲剧了,我alert的时候变成Alice了
       Alan.SetAge(10);//悲剧,被别人把我的年龄给这么小
       alert(Alan.GetName());
       Alan.DisplayAll = function () { return "Name: "+this.GetName() + "; Age: " + this.GetAge() }
       alert(Alan.DisplayAll());

貌似样子很像C#中的Setter和Getter,但是还是可以被外部修改。但是从约束上来看,貌似比上面的code要好看些,通过方法来设置初始值。但是问题还是没有解决,我们来看看下面一种方法:闭包。解释一下,在Javascript中是通过This关键字来开发权限的(Public)。在讲闭包之前,我们需要了解下闭包的本质: 在Javascript中,只有方法是有作用域的,如果在方法中声明的变量在外部是无法访问的,那Private的概念就出来了。

var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge"]);
       var Man = function (newname, newage) {
               var name, age;
               this.SetName = function (newname) { name = newname; }
               this.SetAge = function (newage) { age = newage; }
               this.GetName = function () { return name; }
               this.GetAge = function () { return age; }
               this.SetAge(newage);
               this.SetName(newname);     
       }
       var Alan = new Man("Alan", 25);
       Alan.name="Alice"; //现在name是private了,我是无法去修改的
       Alan.SetAge(10);
      alert(Alan.GetAge());

现在私有的功能就实现了,我们只是用Var来代替了This而已。//我们把公共(Public)并且可以访问Private的方法称为特权方法,比如上面的this.SetName, this.SetAge.

如果我们的公共方法不涉及到访问Private的字段,那我们可以把他们放到Prototype中。//好处是多个实例的时候内存中也只有一分拷贝

Man.prototype.DisplayAll = function () { return "Name: " + this.GetName() + "; Age: " + this.GetAge() }

哈哈~我们来看下稍微有点难度的东西:静态变量和方法。

我们都是知道静态的东西属于类(Class),我们来修改下上面的代码:

var Person = new Interface("Person", ["SetName", "SetAge", "GetName", "GetAge","GetCount"]);
      var Man = (function () {
          var count = 0;
          return function (newname, newage) {
              var name, age;
              this.SetName = function (newname) { name = newname; }
              this.SetAge = function (newage) { age = newage; }
              this.GetName = function () { return name; }
              this.GetAge = function () { return age; }
              this.GetCount = function () { return count; }
              this.SetAge(newage);
              this.SetName(newname);
              count++;
          }
      })();
          Man.prototype.DisplayAll = function () { return "Name: " + this.GetName() + "; Age: " + this.GetAge() }
          var Alan1 = new Man("Alan", 25);
          var Alan2 = new Man("Alan", 25);
     alert("There are "+Alan2.GetCount()+" instances of Man" );

不管我们是通过Alan1或Alan2去GetCount,结果都一样都是2. 这里count就是一个私有的静态变量。

本文地址:http://www.nowamagic.net/librarys/veda/detail/1517,欢迎访问原出处。

不打个分吗?

转载随意,但请带上本文地址:

http://www.nowamagic.net/librarys/veda/detail/1517

如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 加入收藏

大家都在看

现代魔法研究协会欢迎你

阅读一百本计算机著作吧,少年

很多人觉得自己技术进步很慢,学习效率低,我觉得一个重要原因是看的书少了。多少是多呢?起码得看3、4、5、6米吧。给个具体的数量,那就100本书吧。很多人知识结构不好而且不系统,因为在特定领域有一个足够量的知识量+足够良好的知识结构,系统化以后就足以应对大量未曾遇到过的问题。

奉劝自学者:构建特定领域的知识结构体系的路径中再也没有比学习该专业的专业课程更好的了。如果我的知识结构体系足以囊括面试官的大部分甚至吞并他的知识结构体系的话,读到他言语中的一个词我们就已经知道他要表达什么,我们可以让他坐“上位”毕竟他是面试官,但是在知识结构体系以及心理上我们就居高临下。

所以,阅读一百本计算机著作吧,少年!

《重来:更为简单有效的商业思维》 贾森•弗里德(Jason Fried) (作者), 大卫•汉森(David Heinemeier Hansson) (作者), Mike Rohde (插图作者), 李瑜偲 (译者)

这本书呈现的是一种更好、更简单的经商成功之道。读完这本书,你就会明白为什么计划实际上百害而无一益,为什么你不需要外界投资人,为什么将竞争视而不见反倒会发展得更好。事实是你所需要的比你想象的少得多。你不必成为工作狂,你不必大量招兵买马,你不必把时间浪费在案头工作和会议上,你甚至不必拥有一间办公室。所有这些都仅仅是借口!

更多计算机宝库...