javascript实例教程之封装的用法

今天讲讲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就是一个私有的静态变量。

时间: 2024-10-13 10:19:06

javascript实例教程之封装的用法的相关文章

jquery ajax实例教程和一些高级用法

jquery ajax的调用方式:jquery.ajax(url,[settings]),jquery ajax常用参数:红色标记参数几乎每个ajax请求都会用到这几个参数,本文将介绍更多jquery ajax实例,后面会有一些ajax高级用法 query ajax的调用方式:jquery.ajax(url,[settings]),因为实际使用过程中经常配置的并不多,所以这里并没有列出所有参数,甚至部分参数默认值,就是最佳实践,根本没必要去自己定义,除非有特殊需求,如果需要所有参数,可以查看jq

菜鸟学习javascript实例教程

菜鸟学习javascript实例教程 1.用JS显示文字的例子: <html><body> <script type="text/javascript">document.write("Hello World!")</script> </body></html> 2.用HTML标签来格式化文本的例子: <html><body> <script type="

每天一个JavaScript实例-apply和call的用法

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>每天一个JavaScript实例-apply和call的用法</title> <script> function Person(name,age){ //定义一个类,人类

Javascript实例教程:querySelectorAll()方法

querySelectorAll()接受和querySelecort()一样的两个参数,即CSS查询和可选的命名空间解析器,但是返回的是所有匹配的节点而非单个.该方法返回一个叫做StaticNodeList的新类型的实例. 顾名思义,StaticNodeList有NodeList所有的属性和方法,但是它底层的实现是元素集合的一个快照,而非总是要重新的针对文档的动态查询.使用StaticNodeList消除了大部分使用NodeList对象带来的性能问题. 只要调用querySelectorAll(

JavaScript中字符串分割函数split用法实例

这篇文章主要介绍了JavaScript中字符串分割函数split用法,实例分析了javascript中split函数操作字符串的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了JavaScript中字符串分割函数split用法.分享给大家供大家参考.具体如下: 先来看下面这段代码: <script type="text/javascript"> var str="How are you doing today?" document.write

JavaScript强化教程——jQuery AJAX 实例

什么是 AJAX?AJAX = 异步 JavaScript 和 XML(Asynchronous JavaScript and XML).简短地说,在不重载整个网页的情况下,AJAX 通过后台加载数据,并在网页上进行显示.使用 AJAX 的应用程序案例:谷歌地图.腾讯微博.优酷视频.人人网等等. jQuery load() 方法 jQuery load() 方法是简单但强大的 AJAX 方法. load() 方法从服务器加载数据,并把返回的数据放入被选元素中. 语法: $(selector).l

React 入门实例教程

React 入门实例教程 作者: 阮一峰 日期: 2015年3月31日 现在最热门的前端框架,毫无疑问是 React . 上周,基于 React 的 React Native 发布,结果一天之内,就获得了 5000 颗星,受瞩目程度可见一斑. React 起源于 Facebook 的内部项目,因为该公司对市场上所有 JavaScript MVC 框架,都不满意,就决定自己写一套,用来架设 Instagram 的网站.做出来以后,发现这套东西很好用,就在2013年5月开源了. 由于 React 的

JavaScript强化教程——Cocos2d-JS中JavaScript继承

JavaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求.由于Cocos2d-JS引擎是从Cocos2d-x演变而来的,在Cocos2d-JS的早期版本Cocos2d-HTML中几乎全部的API都是模拟Cocos2d-x API而设计的,Cocos2d-x本身是有C++编写的,其中的很多对象和函数比较复杂,JavaScript语言描述起来有些力不从心了.在开源社区中John Resiq在他的博客(http://e

JavaScript强化教程——sessionStorage和localStorage

本文为 H5EDU 机构官方 HTML5培训 教程,主要介绍:JavaScript强化教程 —— sessionStorage和localStorage html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage. sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁.因此sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储. 而