您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

JavaScript设计模式之一封装

2024/5/3 21:32:57发布34次查看
对于熟悉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 alan = new man(alan, 25);      alert(alan.getage());    alan.displayall = function () { return name: +this.getname() + ; age: + this.getage() }   alert(alan.displayall());
我先创建了一个class(javascript的匿名方法)拥有2个公共的(public)的字段(本篇blog会详细讲解,继续往下看)和2个public的方法,我们创建了一个instance--alan,但是我可以为这个instance动态的添加一个displayall的方法,我想任何面向对象的语言是做不到这一点的,javascript的灵活体现之一。
我们现在假设一个场景,如果有很多的程序员要用这段代码,由于javascript的易变性,程序员就可以在实例化后改变name的值,那初始化的动作就没有意义了:
var alan = new man(alan, 25);       alan.name = alice; //悲剧了,我alert的时候变成alice了       alert(alan.getname());
所以我们不能让外部的人去任意的修改这个字段,在java或c#中我们只需要个这个字段改为private,就万事ok了,但是javascript没有这个关键词,那我们需要这么做呢,这就是这篇blog存在的意义
我们可以想下在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 );
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product