JavaScript设计模式之一封装
对于熟悉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" );

不管我们是通过Alan1或Alan2去GetCount,结果都一样都是2. 这里count就是一个私有的静态变量。
至于为什么,不懂的可以回复我的Post,我相信大家都能看懂的~!
JavaScript设计模式之一封装的更多相关文章
- JavaScript设计模式-6.封装
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 《JavaScript设计模式 张》整理
最近在研读另外一本关于设计模式的书<JavaScript设计模式>,这本书中描述了更多的设计模式. 一.创建型设计模式 包括简单工厂.工厂方法.抽象工厂.建造者.原型和单例模式. 1)简单 ...
- 《JavaScript设计模式与开发实践》整理
最近在研读一本书<JavaScript设计模式与开发实践>,进阶用的. 一.高阶函数 高阶函数是指至少满足下列条件之一的函数. 1. 函数可以作为参数被传递. 2. 函数可以作为返回值输出 ...
- Javascript设计模式学习一
学习Javascript设计模式之前,需要先了解一些相关知识,面向对象的基础知识.this等重要概念,以及掌握一些函数式编程的技巧. Js多态 多态的思想:实际上是把“做什么”和“谁去做”分离开来.例 ...
- 常用的Javascript设计模式
<parctical common lisp>的作者曾说,如果你需要一种模式,那一定是哪里出了问题.他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案. 不管是弱类型 ...
- JavaScript设计模式学习笔记
1 JavaScript设计模式深入分析 私有属性和方法:函数有作用域,在函数内用var 关键字声明的变量在外部无法访问,私有属性和方法本质就是你希望在对象外部无法访问的变量. 特权属性和方法:创建属 ...
- JavaScript设计模式:读书笔记(未完)
该篇随我读书的进度持续更新阅读书目:<JavaScript设计模式> 2016/3/30 2016/3/31 2016/4/8 2016/3/30: 模式是一种可复用的解决方案,可用于解决 ...
- JavaScript的学习--JavaScript设计模式的总结
这篇博客只是自己对设计模式的理解的备忘~ 看完了<JavaScript设计模式>这本书,一直没有写博客记录一下,最近抽出时间来重读了一下,就顺便记录一下~ 如果你只是想粗略了解一下Java ...
- JavaScript设计模式 - 迭代器模式
迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺 ...
随机推荐
- Java在linux下调用C/C++生成的so文件
1.CplusUtil.java是java web工程中的一个工具类内容如下:CplusUtil.java package cn.undoner.utils; /** * Created by ${& ...
- 错误 frm-40654 记录已经被另一个用户更新,重新查询以查看修改
导致这问题的原因有多个,有些是最近在项目上发现不同于网上其他人遇到的 网上一般来说大家都说有如下几个原因.但是在项目上做返利时 对AP invoice 的有做更改,导致更改或插入的数据在界面上修 ...
- Java之恋
初次见面那是一个河北的夏天风随沙散落天涯蝴蝶依旧恋着花回首走过的日子手指和键盘之间的梦想之光已恍如昨日 那年我还是一个刚踏进这个曾经只在地理课本上狂念南稻北麦,南油北花的土地那年你只是我必须要学的编程 ...
- [Android游戏开发学习笔记]View和SurfaceView
本文为阅读http://blog.csdn.net/xiaominghimi/article/details/6089594的笔记. 在Android游戏中充当主要角色的,除了控制类就是显示类.而在A ...
- Dynamics CRM2013 更新用户数据主要电子邮件字段报数据加密错误
今天在更新用户数据中的主要邮件字段时报数据 可以进系统设置-数据管理-数据加密中开启,但前提是必须启用https访问而不能用http,在第二个框内输入秘钥点击激活就行了,我这边已经激活过了所以显示的是 ...
- Spark-SQL连接MySql关系型数据库
本文主要分析Spark SQL官方文档中有关于JDBC To Other Databases部分,以MySQL数据库为例,结合数据读写操作的实例代码进行详细的分析.本文中的代码需要使用到Mysql J ...
- FORM中的MOAC控制
1.创建表时,对_ALL表创建同义词 -- Create Multi Org Synonym CREATE OR REPLACE SYNONYM CUX_WF_DEF_HEADER FOR CUX ...
- Java由先序序列和中序序列还原二叉树
还原本来的二叉树并不是一个非常简单的事,虽然思想比较简单,但过程却是比较繁琐.下面我拿先序序列和中序序列来讲一下原理吧. 从先序序列中我们一下子就可以得到二叉树的根节点是第一个元素,然后再中序序列中我 ...
- Java应用程序使用系统托盘资源
要想使自己开发的Java SE项目运行在自己的电脑系统托盘上,这并不是什么难事,总共需要如下几步即可: 1.线判断一下,系统托盘是否可用,否则接下来的程序将不可避免的报出异常咯 2.获得一个Syste ...
- Dynamics Crm2011 Removes an option from an Option Set control
应用场景:OptionSet中有N个option值,特定的条件下需要去除某些option的显示,例如在某个条件下我要红框中的两个option不显示 var purchasetype= Xrm.Page ...