- 浏览: 42085 次
- 性别:
- 来自: 苏州
最近访客 更多访客>>
最新评论
-
dgy:
good boy
Velocity 用户指南手册中文版 -
sujun7758:
good
Velocity 用户指南手册中文版
理论知识
1. 首先Javascript是弱类型语言,它定义变量时不必声明类型,如var Person = new Person(),它的变量类型为“var”,现在的C# 3.0也引进了这种匿名类型的概念,弱类型的变量产生了极大的灵活性,因为Javascript会根据需要来进行类型转换。所以这也决定了它采用了晚绑定的方法,即在运行后才知道变量的类型;
2. 面向对象概念不必多说,封装,继承,多态;
3. Javascript对象的类型主要分为三种:本地对象,如String,Array,Date等;内置对象,如Global,Math等;宿主对象,是指BOM,DOM对象等等;变量范围包括传统面向对象程序设计中的作用域,如公有,保护,私有,静态等等;
主要内容
1. 现在让我们来看看Javascript怎样创建对象的:
function Man() { // } Man.prototype.getNickName = function() { return "Leepy"; }; var man = new Man(); var name = man.getNickName();
这样就创建了最简单的类和对象,其中我们可以把function Man() {} 看作是Man类的构造函数,getNickName()看作是Man类的方法,准确说可以“当作”是Man类的公共方法;为什么要说是当作呢?那是因为其实Javascript实际上并没有一个私有共有的划分,因此开发者们自己指定了这样的规约,那么规约是什么样的呢?我这里把Man类的清单完整地列出来:
function Man() { // 私有静态属性 var Sex = "男"; //私有静态方法 function checkSex() { return (Sex == "男"); } //私有方法 this._getSex = function() { //调用私有静态方法 if(checkSex()) return "男"; else return "女"; } //私有方法 this.getFirstName = function() { return "Li"; }; //私有方法 this.getLastName = function() { return "Ping"; }; } //公共方法 Man.prototype.getNickName = function() { return "Leepy"; }; //公共方法 Man.prototype.getFullName = function() { return this.getFirstName() + " " + this.getLastName(); }; //公共方法 Man.prototype.getSex = function() { //调用私有方法 return this._getSex(); }; //公共静态方法 Man.say = function() { return "Happy new year!"; }
这样的类是否看起来和传统的类很相似了呢
2. 接下来这个是本篇的一个重点,就是用Javascript如何设计一个接口,然后让类继承于它。
首先,先让我们看传统的C#语言是如何设计接口的吧:
public interface Person { string GetName(); void SetName(string name); } public class Man : Person { private string _name; public string GetName() { return _name; } public void SetName(string name) { _name = name; } }
接口中可以声明属性、方法、事件和类型(Structure),(但不能声明变量),但是并不能设置这些成员的具体值,也就是说,只能定义,不能给它里面定义的东西赋值,而接口作为它的继承类或者派生类的规约,继承类或者它的派生类能够共同完成接口属性、方法、事件和类型的具体实现,因为这里GetName(),SetName(),不管是方法名还是属性调用顺序上都是要保持一致的;
那么有了这样的一个基于接口的思想,我们设计Javascript的接口类的时候也需要考虑到这个规范。我先从主JS文件调用端开始说起:
var Person = new Interface("Person", [["getName", 0], ["setName", 1]]);
其中Interface类是稍后要说的接口类,第一个参数"Person"是接口类的名称,第二个参数是个二维数组,"getName"是接口方法的名称,"0"是该方法所带的参数个数(因为Javascript是弱语言,所以类型是不确定的,所以只要记住参数个数就好,"0"可以省略不写),"setName"同理。这样一个接口定义好了。怎样使用它呢?
function Man() { this.name = ""; Interface.registerImplements(this, Person); } Man.prototype.getName = function() { return this.name; }; Man.prototype.setName = function(name) { this.name = name; };
看到Man的构造函数里面包含
Interface.registerImplements(this, Person);
它是用来将实例化的this对象继承于Person接口,然后继承类对接口的方法进行实现。
代码看起来是不是很清晰和简单呢^_^,那么现在要开始介绍真正的核心代码Interface.js了:
先看Interface的构造函数部分
function Interface(name, methods) { if(arguments.length != 2) { throw new Error("接口构造函数含" + arguments.length + "个参数, 但需要2个参数."); } this.name = name; this.methods = []; if(methods.length < 1) { throw new Error("第二个参数为空数组."); } for(var i = 0, len = methods.length; i < len; i++) { if(typeof methods[i][0] !== 'string') { throw new Error("接口构造函数第一个参数必须为字符串类型."); } if(methods[i][1] && typeof methods[i][1] !== 'number') { throw new Error("接口构造函数第二个参数必须为整数类型."); } if(methods[i].length == 1) { methods[i][1] = 0; } this.methods.push(methods[i]); } };
刚才看到了var Person = new Interface("Person", [["getName", 0], ["setName", 1]]);,这里将两个参数分别保存起来;
调用方法部分:
Interface.registerImplements = function(object) { if(arguments.length < 2) { throw new Error("接口的实现必须包含至少2个参数."); } for(var i = 1, len = arguments.length; i < len; i++) { var interface = arguments[i]; if(interface.constructor !== Interface) { throw new Error("从第2个以上的参数必须为接口实例."); } for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) { var method = interface.methods[j][0]; if(!object[method] || typeof object[method] !== 'function' || object[method].getParameters().length != interface.methods[j][1]) { throw new Error("接口的实现对象不能执行" + interface.name + "的接口方法" + method + ",因为它找不到或者不匹配."); } } } };
刚才这句Interface.registerImplements(this, Person);,实际上这里是把this对象的方法名以及参数个数与刚Person保存的methods逐一进行比较,如果找不到或者不匹配,就警告错误;其中object[method].getParameters().length,调用了如下的代码:
Function.prototype.getParameters = function() { var str = this.toString(); var paramString = str.slice(str.indexOf('(') + 1, str.indexOf(')')).replace(/\s*/g,''); //取得参数字符串 try { return (paramString.length == 0 ? [] : paramString.split(',')); } catch(err) { throw new Error("函数不合法!"); } }
getParrameters()方法作为Function对象的一个扩展,功能是取得方法含有的参数数组;
Interface.js完整的代码如下:
Interface.js文件 function Interface(name, methods) { if(arguments.length != 2) { throw new Error("接口构造函数含" + arguments.length + "个参数, 但需要2个参数."); } this.name = name; this.methods = []; if(methods.length < 1) { throw new Error("第二个参数为空数组."); } for(var i = 0, len = methods.length; i < len; i++) { if(typeof methods[i][0] !== 'string') { throw new Error("接口构造函数第一个参数必须为字符串类型."); } if(methods[i][1] && typeof methods[i][1] !== 'number') { throw new Error("接口构造函数第二个参数必须为整数类型."); } if(methods[i].length == 1) { methods[i][1] = 0; } this.methods.push(methods[i]); } }; Interface.registerImplements = function(object) { if(arguments.length < 2) { throw new Error("接口的实现必须包含至少2个参数."); } for(var i = 1, len = arguments.length; i < len; i++) { var interface = arguments[i]; if(interface.constructor !== Interface) { throw new Error("从第2个以上的参数必须为接口实例."); } for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++) { var method = interface.methods[j][0]; if(!object[method] || typeof object[method] !== 'function' || object[method].getParameters().length != interface.methods[j][1]) { throw new Error("接口的实现对象不能执行" + interface.name + "的接口方法" + method + ",因为它找不到或者不匹配."); } } } }; Function.prototype.getParameters = function() { var str = this.toString(); var paramString = str.slice(str.indexOf('(') + 1, str.indexOf(')')).replace(/\s*/g,''); //取得参数字符串 try { return (paramString.length == 0 ? [] : paramString.split(',')); } catch(err) { throw new Error("函数不合法!"); } }
好了该创建一个html页面来试试效果了:
<script type="text/javascript"> function test() { var man = new Man(); man.setName("Leepy"); alert(man.getName()); } </script> <input type="button" value="click" onclick="test();" />
最终结果为:"Leepy"的弹出框;
这里还有一点要强调,如果接口上的方法没有在继承类上得到完全实现,或者方法参数个数不匹配,那么就会提示错误;
3. 如果我要一个类继承于另一个类该怎么做呢,继续看例子,这里我再定义一个SchoolBoy(男学生)类:
function SchoolBoy(classNo, post) { Man.call(this); this._chassNo = classNo; this._post = post; } SchoolBoy.prototype = new Man(); SchoolBoy.prototype.getName = function() { return "Mr " + this.name; } SchoolBoy.prototype.setName = function(name) { this.name = name + "'s"; }
其中Man.call(this);实际上是将Man中的关键字this赋值于SchoolBoy对象中去,那么SchoolBoy就拥有了Man构造函数中的name属性了;
SchoolBoy.prototype = new Man();实际上是把Man的prototype赋值给SchoolBoy.prototype,那么SchoolBoy就有了Man类中的方法;
而后面跟着的getName(),setName(),实际上是覆盖了前面继承于Man类中的方法了;
然后看看效果:
var schoolboy = new SchoolBoy("三年二班", "班长"); schoolboy.setName("周杰伦"); alert(schoolboy.getName());
最后结果为:"Mr 周杰伦's"的弹出框;
总结
该篇文章主要讲述一些Javascript面向对象的基础以及接口和继承类的实现等等;下一篇将开始真正的Javascript设计模式征程,并且我会结合一些网站系统上的实例来讲;
本文来自:http://www.cnblogs.com/liping13599168/archive/2009/01/03/1367334.html
发表评论
-
网页特殊符号HTML代码大全
2010-06-11 09:00 1863... -
jQuery、prototype、mootools、YUI框架比较
2009-12-15 16:36 1856个人觉得:mootools 更符合面向对象,易扩展,对于熟悉面 ... -
10个新的最有前途的JavaScript框架
2009-11-16 11:40 10751. SproutCore SproutCore ... -
JavaScript的gzip静态压缩传输方法
2009-11-02 09:41 1468传统的JS压缩(删除注释,删除多余空格等)提供的 ... -
用javascript动态加载不同css/js文件
2009-11-02 09:35 2155先导入js文件。 DynamicLoad.js文件代码如下: ... -
JS动态载入外部JS文件
2009-11-02 09:28 2070我们经常把一大堆的JS文件在页面载入的时候就全部载入,可这样就 ... -
Js 跨域调用问题
2009-10-21 16:30 930Javascript出于安全性考虑,是不允许跨域调用其他页面的 ... -
什么是flickr及flickr的简史
2009-10-14 10:42 2428Flickr为一家提供免费及 ... -
国外开放API面面观:15个API介绍!
2009-10-13 22:42 2006国外的2.0服务多又成熟,API是专又全,除了现在过热的Fac ... -
悟透JavaScript (2)
2009-09-28 10:29 972在JavaScript内部,对象的属性和方法追溯机制是通过所谓 ... -
悟透JavaScript(1)
2009-09-28 09:18 707引子 编程世界里 ...
相关推荐
对话框乱弹的小程序,点击开始后会不停弹300个大小不等位置不确定的对话框,伴随windows的一些报警声,很有节奏的感觉。
使用fiddler工具进行抓包,使用python进行osc乱弹抢沙发
《浅析新媒介生态环境下广播娱乐节目的编辑特征——以FM101.1西安乱弹“刘翔来了”为例》-论文.zip
into沙龙第期康国庆乱弹传统企业转型以及与互联网结合的方式PPT教案.pptx
修复单类代码生成器4个问题。 2.新增创建加载数据库时,表名过滤功能。 3.表名生成命名规则,字符串替换功能。 4.模板中字段排序方法公开。 5.字段默认值函数的处理。 6.导出的sql脚本中,单引号 '的问题。 7.工具-...
乱弹随机跳转到博客的任意一篇文章。TotoroⅢ,基于TotoroII的Z-Blog的评论及引用管理审核系统增强版。 8月1号发布,修正了0722版的一些问题,请大家更新! 主要更新 [主要更新]后台语言包切换 [主要更新]WAP插件...
随着Ajax技术的出现、盛行,本被忽视认为是二流编程语言的JavaScript脚本也开始了新的盛行,大量的JavaScript框架的出现如Microsoft Asp.Net Ajax、jQuery等。Ajax已经成为这些脚本框架必不可少的组成部分了,而且...
第1章 设计的数据和分析 1 看不懂数据 2 不配看数据 2 为了看数据而看数据 2 不去筛选数据 3 不关注数据采集的方式和方法 4 只用定量数据,没有定性数据 5 设计中的数据分析 5 数据——判断淘宝店铺页面设计优劣的...
《浅析新媒介生态环境下广播娱乐节目的编辑特征——以FM101.1西安乱弹“刘翔来了”为例》.zip
《浅析新媒介生态环境下广播娱乐节目的编辑特征——以FM101.1西安乱弹“刘翔来了”为例》.doc
数据可视化基础
hive是一个基于hadoop上面提供了类sql的接口的组件,以方便熟悉sql的人使用hadoop,对大数据的处理。限于精力,本文只关注hive所提供的语法,它解析语法的过程,以及生成执行计划和优化这几个过程。 本文可以作为...
利用GestureDetector实现页面滑动Demo
自定义View实现Android快速索引,模仿微信的通讯录效果。右侧的快速索引条按下时候没有变成灰色,但是我设置了selector,不知道为什么没有生效,请知道原因的朋友告诉我一下,感激了。
现在此版本war包已上传至本站附件栏,并经过详细测试,有重大Bug修复与功能更新,涉及一系列遗漏的Bug修复,包括Excel模板生成的一些缺陷,和Boolean类型的一系列缺陷,已发现的Bug均已修复,欢迎下载使用。
6.1. 有了它,我们就可以摆脱那些自称ui设计师的人了。 6.2. 关于BorderLayout 6.3. 嗯,不如再看看附加效果 6.3.1. 先看看split 6.3.2. 再试试titlebar 6.3.3. 还不够,还不够,让四周的区域可以缩起来 ...
本文由林氏原创,遵循GPL许可,你可以自由地对本文进行任何目的的修改、转载、引用和发布,但基于此文所作的任何修改、转载、引用和发布品也需要遵循GPL许可,并要求在开头保留本声明。 联系作者:如果您有什么样的...
进行编译,并嵌入到可执行文件中去pyHook-1.5.1.win32-py2.7