JavaScript 封装设计模式介绍
对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,那么如何在Javascript中利用封装这个特性呢?
我们会把现实中的一些事物抽象成一个Class并且把事物的属性(名词)作为Class的Property把事物的动作(动词)作为Class的methods。在面向对象的语言中(C#等)都会有一些关键字来修饰类或者属性(Private,public,protect),这些关键词描述了访问的权限,不多做解释。
我们来看看Javascript的易变的特性(我们还用上一次的例子):
01
|
var Man = function (name, age) {
|
02
|
this .Name = name;
|
03
|
this .Age = age;
|
04
|
}
|
05
|
var Person = new Interface( "Person" , [ "GetName" , "GetAge" ]);
|
06
|
Man.prototype = { GetName: function () { return this .Name; },
|
07
|
GetAge: function () { return this .Age; }
|
08
|
}
|
09
|
var Gonn = new Man( "Gonn" , 25);
|
10
|
alert(Gonn.GetAge());
|
11
|
Gonn.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() }
|
12
|
alert(Gonn.DisplayAll());
|
先创建了一个Class(Javascript的匿名方法)拥有2个公共的(public)的字段(本篇blog会详细讲解,继续往下看)和2个public的方法,我们创建了一个Instance--Gonn,但是我可以为这个Instance动态的添加一个DisplayAll的方法,我想任何面向对象的语言是做不到这一点的,Javascript的灵活体现之一。
现在假设一个场景,如果有很多的程序员要用这段代码,由于Javascript的易变性,程序员就可以在实例化后改变Name的值,那初始化的动作就没有意义了:
1
|
var Gonn = new Man( "Gonn" , 25);
|
2
|
Gonn.Name = "Alice" ;
|
3
|
alert(Gonn.GetName());
|
所以我们不能让外部的人去任意的修改这个字段,在Java或C#中我们只需要个这个字段改为Private,就万事OK了,但是Javascript没有这个关键词,那我们需要这么做呢。我们可以想下在C#除了设置Private之外我们还可以怎么做?我们可以设置Setter和Getter方法。
我们来修改下上面的代码:我们称方法一:
01
|
var Person = new Interface( "Person" , [ "SetName" , "SetAge" , "GetName" , "GetAge" ]);
|
02
|
var Man = function (name, age) {
|
03
|
this .SetAge(age);
|
04
|
this .SetName(name);
|
05
|
}
|
06
|
Man.prototype = {
|
07
|
SetName: function (name) { this .Name = name; },
|
08
|
SetAge: function (age) { this .Age = age; },
|
09
|
GetName: function () { return this .Name; },
|
10
|
GetAge: function () { return this .Age; }
|
11
|
}
|
12
|
var Alan = new Man( "Alan" , 25);
|
13
|
Alan.Name = "Alice" ; //悲剧了,我alert的时候变成Alice了
|
14
|
Alan.SetAge(10); //悲剧,被别人把我的年龄给这么小
|
15
|
alert(Alan.GetName());
|
16
|
Alan.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() }
|
17
|
alert(Alan.DisplayAll());
|
貌似样子很像C#中的Setter和Getter,但是还是可以被外部修改。但是从约束上来看,貌似比上面的code要好看些,通过方法来设置初始值。但是问题还是没有解决,我们来看看下面一种方法:闭包。解释一下,在Javascript中是通过This关键字来开发权限的(Public)。在讲闭包之前,我们需要了解下闭包的本质: 在Javascript中,只有方法是有作用域的,如果在方法中声明的变量在外部是无法访问的,那Private的概念就出来了。
01
|
var Person = new Interface( "Person" , [ "SetName" , "SetAge" , "GetName" , "GetAge" ]);
|
02
|
var Man = function (newname, newage) {
|
03
|
var name, age;
|
04
|
this .SetName = function (newname) { name = newname; }
|
05
|
this .SetAge = function (newage) { age = newage; }
|
06
|
this .GetName = function () { return name; }
|
07
|
this .GetAge = function () { return age; }
|
08
|
this .SetAge(newage);
|
09
|
this .SetName(newname);
|
10
|
}
|
11
|
var Alan = new Man( "Alan" , 25);
|
12
|
Alan.name= "Alice" ; //现在name是private了,我是无法去修改的
|
13
|
Alan.SetAge(10);
|
14
|
alert(Alan.GetAge());
|
现在私有的功能就实现了,我们只是用Var来代替了This而已。//我们把公共(Public)并且可以访问Private的方法称为特权方法,比如上面的this.SetName, this.SetAge.
如果我们的公共方法不涉及到访问Private的字段,那我们可以把他们放到Prototype中。//好处是多个实例的时候内存中也只有一分拷贝
1
|
Man.prototype.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() }
|
哈哈~我们来看下稍微有点难度的东西:静态变量和方法。
我们都是知道静态的东西属于类(Class),我们来修改下上面的代码:
01
|
var Person = new Interface( "Person" , [ "SetName" , "SetAge" , "GetName" , "GetAge" , "GetCount" ]);
|
02
|
var Man = ( function () {
|
03
|
var count = 0;
|
04
|
return function (newname, newage) {
|
05
|
var name, age;
|
06
|
this .SetName = function (newname) { name = newname; }
|
07
|
this .SetAge = function (newage) { age = newage; }
|
08
|
this .GetName = function () { return name; }
|
09
|
this .GetAge = function () { return age; }
|
10
|
this .GetCount = function () { return count; }
|
11
|
this .SetAge(newage);
|
12
|
this .SetName(newname);
|
13
|
count++;
|
14
|
}
|
15
|
})();
|
16
|
Man.prototype.DisplayAll = function () { return "Name: " + this .GetName() + "; Age: " + this .GetAge() }
|
17
|
var Alan1 = new Man( "Alan" , 25);
|
18
|
var Alan2 = new Man( "Alan" , 25);
|
19
|
alert( "There are " +Alan2.GetCount()+ " instances of Man" );
|
不管我们是通过Alan1或Alan2去GetCount,结果都一样都是2. 这里count就是一个私有的静态变量
转载:http://www.nowamagic.net/librarys/veda/detail/1517
JavaScript 封装设计模式介绍相关推荐
- 7 种 Javascript 常用设计模式学习笔记
7 种 Javascript 常用设计模式学习笔记 由于 JS 或者前端的场景限制,并不是 23 种设计模式都常用. 有的是没有使用场景,有的模式使用场景非常少,所以只是列举 7 个常见的模式 本文的 ...
- javascript各种设计模式
javascript各种设计模式 设计模式之单例模式 设计模式之构造函数模式 设计模式之建造者模式 设计模式之工厂模式 设计模式之代理模式 设计模式之命令模式 设计模式之原型模式 看了这么多模式之后, ...
- Javascript乱弹设计模式系列(1) - 观察者模式(Observer)
前言 博客园谈设计模式的文章很多,我也受益匪浅,包括TerryLee.吕震宇等等的.NET设计模式系列文章,强烈推荐.对于我,擅长于前台代码的开发,对于设计模式也有一定的了解,于是我想结合Javasc ...
- JavaScript常见设计模式
Javascript常⻅设计模式 设计模式总的来说是一个抽象的概念,是软件开发人员在开发过程中面临的一般问题的解决方案.这些解决方案是众多软件开发人员经过相当⻓的一段时间的试验和错误总结出来的. 1 ...
- javaScript封装的各种写法
javaScript封装的各种写法 在javascript的世界里,写法是个神奇的现象,真是百家齐开放啊!每次看到老外写的js组件,思想和写法都怪异,就没看到一个js结构基本相同的代码出来.今天,我就 ...
- 23种设计模式介绍以及在Java中的实现
本文章出自:blog.csdn.net/anxpp/artic- 若要查看原文请点击 文章中的示例源码在github上:github.com/anxpp/JavaD- 由于CSDN上的下拉翻页比较麻烦 ...
- 23种设计模式介绍(Python示例讲解)
文章目录 一.概述 二.设计模式七种原则 三.设计模式示例讲解 1)创建型模式 1.工厂模式(Factory Method) [1]简单工厂模式(不属于GOF设计模式之一) [2]工厂方法模式 2.抽 ...
- php js写法,javaScript封装的各种写法
这篇文章主要介绍了javaScript封装的各种写法,通过列举优缺点和使用场景详细介绍了几种JavaScript封装的格式,对JavaScript的感兴趣朋友可以参考下本篇文章 在javascript ...
- golang设计模式介绍(内含各个模式的java对比)代码解读
golang设计模式介绍 设计模式是面向对象软件的经验,是通常设计问题的解决方案,每一种设计模式系统的命名,解释和评价了面向对象中一个重要的和重复出现的设计. 以下一一介绍这些设计模式 1.1工厂设计 ...
最新文章
- SAP SD基础知识之订单中装运相关的功能 II
- ES-PHP向ES批量添加文档报No alive nodes found in your cluster
- 谷歌浏览器chrome的vuejs devtools 插件的安装
- 用python爬取网页数据并存入数据库中源代码_Python爬取51cto数据并存入MySQL方法详解...
- 窗体中实现按 回车键 跳到下一个可选的TabIndex控件
- Mac下matplotlib中文显示
- 能伸能屈的拼音及解释
- 小菜的系统框架界面设计-小菜用户权限管理软件开源大放送
- Java多用户商城系统B2B2C源码
- 用excel绘制统计图
- php实现推箱子游戏,C语言实现推箱子游戏的代码示例
- python excel转csv日期变数字_将Excel转换为CSV正确转换日期字段
- Level/levelup-1-简介
- SpringBoot resultful风格返回格式
- 说一说关于破解支付宝AR红包的事
- angular打包文件目录及访问地址
- 在c#中,筛选一个List中的每个元素的开头或结尾是否包含另一个List的元素(StartWith()的使用)...
- 新概念二册 Lesson 31 Success story成功者的故事 (used to do + it 做形式主语)
- 卡西欧函数计算机广告词,学生专用卡西欧函数计算器简易空间里的排列
- 如何收取google adsense广告费?招行一卡通电汇设置指南