JS 4 新特性:混合属性(mixins)之二
Mixins many classes【混合许多个类】
迄今为止,我们已经学会了简单的继承,我们还能够通过使用mixins处理机制来混合许多类。源于这种理念是非常简单的;我们能够把许多个类最终混合到一个类去,最后的结果就是,新产生的类(在内部)能够通过mixings类来访问到那这些类中的方法和属性。
举个例子:我要做一个应用程序,是花样滑冰运动员和冰上舞蹈运动员的参加竞赛程序,一项竞赛程序就是一系列跳跃、旋转、滑步等动作的组合,裁判员根据每个运动员参加竞赛做的动作元素技术和移动水平来打分。
单纯的冰上花样滑冰需要去跳跃、旋转和做一些滑步动作,但对于冰上舞蹈来说它不允许有跳跃动作,只有旋转和滑步动作。
我们将把跳跃、旋转、滑步做成三个大类,其中每个类中都有我们需要的动作元素,这样滑冰运动员在竞赛程序中都拥有了自己要做的动作元素。
首先,我们需要建立以一个跳跃类,内含不同类型的跳跃动作。如果以后觉得还有新类型的跳跃动作没有定义的话,那我们很方便的在这个类中加入一个新的方法就可以。
(注:跳跃类为MyApp.skating.Jump,定义了waltz华尔兹式跳跃、axel前外一周半跳跃、split空中劈叉跳跃三种。因此我们定义了第1个类,如下:)
1 //定义第1个类:跳跃类 2 Ext.define('MyApp.skating.Jump', { 3 waltz: function(){ 4 console.log("waltz:华尔兹式跳跃,一周半旋转式跳跃,为前外一周半跳的最基本动作"); 5 }, 6 axel: function(){ 7 console.log("axel:1.5式跳跃,在花样滑冰中实际上就前外旋转一周半式跳跃"); 8 }, 9 split: function(){ 10 console.log("split:空中劈叉式跳跃,或是一个跳跃、后外钩点冰一周跳,或以环形起跳冰在空中来个大劈叉或者一个大跨越式动作"); 11 }, 12 //测试相同函数 13 combination : function(){ 14 console.log("这是Jump类的combination方法!"); 15 } 16 });
为了简单起见,在程序中我们仅仅向firefox的控制台发送一个log信息,以便于说清楚问题就行了。
现在,再建立第二个类Spin旋转,包含一个滑冰运动员所能做到得不同类型的旋转动作。
1 //定义第2个类:旋转类 2 Ext.define('MyApp.skating.Spin', { 3 scratch: function(){ 4 console.log("scratch:擦式旋转,自由腿交叉在滑冰腿的前面进行旋转动作"); 5 }, 6 crossfoot: function(){ 7 console.log("crossfoot:交叉腿旋转,自由腿和滑冰腿前后交叉旋转动作,就像轮滑一样"); 8 }, 9 camel: function(){ 10 console.log("camel:驼转,自由腿的膝盖要高于臀部的旋转动作"); 11 }, 12 //测试相同函数 13 combination : function(){ 14 console.log("这是Spin旋转类的combination方法!"); 15 } 16 }); 17
我们最后一个类是滑步动作类FootWork,它能偶代表参赛选手在冰上所做到得滑步动作。
1 //定义第3个类:滑步类 2 Ext.define('MyApp.stepssequence.Footwork', { 3 mohawk: function(){ 4 console.log("mohawk:莫霍步式滑步,通常是在一个圆线或曲线上呈逆时针方向做完滑步,其实就是怎么转弯的问题。"); 5 }, 6 spreadeagle: function(){ 7 console.log("spreadeagle:用双脚着地向鹰隼一样伸展滑步。"); 8 }, 9 twizzles: function(){ 10 console.log("twizzles:多姿乐。在花样滑冰中采用一只脚变旋光作用下滑步。"); 11 } 12 });
目前,在三个类中我们已经有了滑冰运动员要做的动作了,下一步还需要为每一个滑冰员添加上相应的动作,那么就应该在程序中添加上,就以花样滑冰运动员开始吧,它具有跳跃、旋转、滑步三类所有情况。
//二、定义花样滑冰运动员,内含三类情况。
1 //二、定义花样滑冰运动员,内含三类情况。 2 Ext.define('MyApp.figure.Skater', { 3 extend : 'Ext.util.Observable', //第1步 4 mixins : { //第2步 5 jump : 'MyApp.skating.Jump', 6 spin : 'MyApp.skating.Spin', 7 footwork : 'MyApp.stepssequence.Footwork' 8 }, 9 10 constructor : function(options){ 11 Ext.apply(this,options); //第3步 12 }, 13 14 compete : function(){ 15 var me = this; 16 console.log(me.name+" 来自 "+me.nationality+" 的花样滑冰运动员开始节目! 祝好运!"); 17 me.waltz(); 18 me.mohawk(); 19 me.camel(); 20 me.axel(); 21 me.spreadeagle(); 22 me.scratch(); 24 console.log(me.name+" 结束节目并获得了第一名!"); 25 } 26 27 });
·第1步:我们继承了Observable类,这个类允许我们去模板events 和listeners,在以后的章节中会介绍,现在使用它作为1个例子了解就行。
·第2步:继使用了mixins关键字来支持这个类,有了mixins我们这个'MyApp.figure.Skater',才能够去访问参与了mixins中所有的跳跃、旋转、滑步类的方法和属性。这是我们的学习点。
· 第3步:使用了构造造函数,这里接受了一个参数options一也是1个在运行时产生的对象,这将允许我们去简单的配置1个花样滑冰运动员的实例。
· 第4步: 我们创建了compete()方法,它建立了滑冰员参加竞赛的动作,注意的是,它实际上是让你学习如何调用参与了mixins类中的方法,我们能够任意调用Jump类、Spin类、FootWork类中的所有方法了!并且当创建1个实例对象的时候,还允许同时创建带有有参数name和nationality,参数丰富了这个花样滑冰运动员实例。
1 // 开始:建立1个花样滑冰运动员的对象,并带有name和nationality参数,调用compete()。 2 var shenxue = Ext.create('MyApp.figure.Skater',{ 3 name : '申雪', 4 nationality : '中国' 5 }); 6 shenxue.compete(); 7 shenxue.combination(); 8 shenxue.mixins.spin.combination();
运行结果图:
现在,我们需要去创建一个冰上舞蹈运动员,他们不允许有跳跃Jump类,但允许有更多的旋转和滑步动作,如下:
1 //三、定义冰上舞蹈运动员,不允许跳跃类,含有Spin类和footWork类。 2 Ext.define('MyApp.dancing.Skater',{ 3 extend : 'Ext.util.Observable', 4 mixins : { //第1步 5 spin : 'MyApp.skating.Spin', 6 footwork : 'MyApp.stepssequence.Footwork' 7 }, 8 9 constructor : function(options){ //第2步 10 Ext.apply(this,options) 11 }, 12 13 compete : function(){ 14 var me = this; 15 console.log(me.name+" 来自 "+me.nationality+"冰上舞蹈运动员开始节目! 祝好运!"); 16 me.camel(); 17 me.scratch(); 18 me.spreadeagle(); 19 me.twizzles(); 20 me.camel(); 21 22 console.log(me.name+" 结束节目并获得优秀的成绩!"); 23 } 24 });
·第1步:为冰上舞蹈者混合Spin旋转类和FootWork滑步类,但是我们还可以混合更多的类。
· 第2步:使用了构造函数,如果你仔细的话,会发现这与花样滑冰者的构造函数一模一样。
· 第3步:我们创建了compete()方法,内仅仅包含对spin类和FootWork类的调用。
1 //开始:建立1个冰上舞蹈运动员,并带有name和nationality参数,调用compete(). 2 var susan = Ext.create('MyApp.dancing.Skater',{ 3 name : '苏珊', 4 nationality : '美国' 5 }); 6 susan.compete();
运行结果图:
《程序结束》
结论:关于mixins最重要的事情是:我们可以创建多个独立的类,每一个类都具有完成指定的任务,然后把这些类mixins到一个混合后的类,这样就可以用混合后的类来重复的调用任务。(例如me.camel();)