作家
登录

Prototype Class对象学习

作者: 来源:www.28hudong.com 2013-03-30 02:28:25 阅读 我要评论

复制代码 代码如下:/* Based on Alex Arnell's inheritance implementation. */ var Class = (function() { //临时存储parent的prototype function subclass() {}; //创建类的方法 function create() { var parent = null, properties = $A(arguments); //检查新建一个类时,是否指定了一个父对象 //如果指定了父类,赋值给parent if (Object.isFunction(properties[0])) parent = properties.shift(); //真正用作返回的类,在创建实例时,将调用initialize方法进行初始化 function klass() { this.initialize.apply(this, arguments); } //给klass添加addMethods方法,在调用create方法之后 //仍可以调用addMethods方法进行类级别的方法扩充 Object.extend(klass, Class.Methods); //给返回的类添加两个属性,superclass:父类,subclasses:子类的集合 klass.superclass = parent; klass.subclasses = []; //如果创建类时指定了父对象,则把klass的原型指向父对象的实例,实现原型链继承 if (parent) { subclass.prototype = parent.prototype; klass.prototype = new subclass; //为父类添加子类,维护父类的子类集合 parent.subclasses.push(klass); } //向新类添加方法 for (var i = 0; i < properties.length; i++) klass.addMethods(properties[i]); //如果没有指定初始化方法,则默认把一个空方法赋给初始化方法 if (!klass.prototype.initialize) klass.prototype.initialize = Prototype.emptyFunction; /* * 修正新类的构造函数,使得构造函数指向自己,这里特意说一下(如果注释掉下面这行): * var Person=Class.create(); * var p1=new Person(); * alert(p1.constructor==Person) //true * var Man=Class.create(Person) * var m1=new Man(); * alert(m1.constrcutor==Man) //false * alert(m1.constrcutor==Person) //true * alert(m1.construcctor==p1.constrcutor) //true * * 看出问题来了吧?Man的构造函数竟然指向了Person的构造函数 * 问题的根源在klass.prototype = new subclass;这句话 * 具体原因我就不解释了,要详细理解的请查看《JavaScript语言精髓与编程实践》155~160页 */ klass.prototype.constructor = klass; return klass; } //把创建类时的方法添加到新类,或者在创建完类之后在添加类级别的方法 function addMethods(source) { //取得新类的父类 var ancestor = this.superclass && this.superclass.prototype; var properties = Object.keys(source); //貌似下面的判断总是为真,不知道为什么这么写,知道的告诉我? if (!Object.keys({ toString: true }).length) { //如果新类重写了toString和valueOf方法则添加之 if (source.toString != Object.prototype.toString) properties.push("toString"); if (source.valueOf != Object.prototype.valueOf) properties.push("valueOf"); } //遍历所有的新类声明中的方法 for (var i = 0, length = properties.length; i < length; i++) { //property是函数名称,value是函数体 var property = properties[i], value = source[property]; //判断这个方法是否需要调用父类的同名方法 if (ancestor && Object.isFunction(value) && value.argumentNames().first() == "$super") { var method = value; //这里很重要! //替换$super参数,使得这个参数指向父类的同名方法 //这里应用了Function的wrap方法,wrap方法的解释请参考【Prototype 学习——Function对象】 //method是新定义的方法,所以他的第一个参数为$super,然后从'='到'.'之间返回的是父类的同名方法 //最后调用wrap方法把$super参数替换成父类的同名方法,这样在子类调用$super()时,将调用父类的同名方法 //这里构造的非常棒!值得思考 value = (function(m) { return function() { return ancestor[m].apply(this, arguments); }; })(property).wrap(method); //将新产生的value(即经过修改过的子类方法)的valueOf和toString指向原子类的同名方法 //这里是在修正调用wrap方法之后的遗留问题 value.valueOf = method.valueOf.bind(method); value.toString = method.toString.bind(method); } //把方法添加到新类中 this.prototype[property] = value; } return this; } //返回Class的可调用方法 return { create: create, Methods: { addMethods: addMethods } }; })();这个类就提供了2个方法:create和addMethods,上面的源码注释中已经说明的很清楚了,下面就看些例子,具体说明一下用法: 复制代码 代码如下://声明Person类,并定义初始化方法 var Person = Class.create({ initialize: function(name) { this.name = name; }, say: function(message) { return this.name + ': ' + message; } }); // when subclassing, specify the class you want to inherit from var Pirate = Class.create(Person, { // redefine the speak method //注意这里的$super用法,在对照源码中的解释仔细看一下 say: function($super, message) { return $super(message) + ', yarr!'; } }); var john = new Pirate('Long John'); john.say('ahoy matey'); // -> "Long John: ahoy matey, yarr!" 复制代码 代码如下:var john = new Pirate('Long John'); john.sleep(); // -> ERROR: sleep is not a method // every person should be able to sleep, not just pirates! //这里是addMethods的用法,可以在类级别扩充方法 Person.addMethods({ sleep: function() { return this.say('ZzZ'); } }); john.sleep(); 复制代码 代码如下://这里是superclass和subclasses两个属性的用法 Person.superclass // -> null Person.subclasses.length // -> 1 Person.subclasses.first() == Pirate // -> true Pirate.superclass == Person // -> true 三个例子几本覆盖了Class类的方法,详细例子请参考:http://prototypejs.org/learn/class-inheritance

  推荐阅读

  javascript 表单规则集合对象

复制代码 代码如下:<script type="text/javascript"> //更多的验证可以继续添加到errMsg对象里 var errMsg={ required:{ msg:"This field is required.", //load参数指定是否在加载的时候验证 test:function(obj,l>>>详细阅读


本文标题:Prototype Class对象学习

地址:http://www.17bianji.com/kaifa2/JS/28415.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)