createjs吧 关注:124贴子:776
  • 10回复贴,共1
因为大多数人写createjs都在an或者直接在网页上写,而不使用脚手架搭建的,所以本篇只介绍es5下的OOP,如果你会使用es6或者TS,那么直接用es6和TS常规的OOP写法即可。


IP属地:浙江1楼2024-10-11 10:29回复
    OOP大家都知道就是面向对象编程,对于程序构建,特别是大项目,可以说是必不可少的。可以用它来降低开发难度,提高代码的重用率等等。在createjs里可以用它特有的写法和api来实现OOP。无论你是从as转到js,还是本来就是写js的,学会在createjs里使用OOP编程都是很重要的,废话不多说,我直接讲下怎么在createjs里使用OOP。
    (不懂OOP的请先了解OOP后再看本教程)


    IP属地:浙江2楼2024-10-11 10:29
    回复
      1.类一般语言(我先拿as作为例子),生成一个类一般是
      public class MainView 然后调用的是 new MainView()这样子,在js里没有类这个概念,但是我们可以模仿,写一个差不多的。
      我们先写出类:
      function Map()
      {
      this.name = "中国"
      }
      var map = new Map();
      console.log(map.name)
      可以看到我们就输出了地图,这里的Map相当于构造函数


      IP属地:浙江3楼2024-10-11 10:30
      回复
        2.闭包
        (function() {
        function Map()
        {
        this.name = "地图"
        }
        var map = new Map();
        }());
        console.log(map);
        大家上面还看到了一个(function() {}());这个格式的语法吧,这个东西干嘛用的呢,做过前端的童鞋肯定知道,它叫闭包。简单的来说吧,就是防止变量之间污染,js与类java语言不一样,类java语言比如as3,他在类里面var的变量只在类里面有用,但是js是都有用,这样的话项目一大变量之间就容易相互污染,而闭包可以很好的解决这问题,写as3转js的童鞋可以把它当做package包。这里的console因为在包外面,所以会报错。


        IP属地:浙江4楼2024-10-11 10:31
        回复
          3.继承
          继承是非常重要的OOP方法,思考一下你做游戏的时候要new10个不同的角色,如果他们都间接继承与一个基础角色类,那么你要统一改他们的方法,只需要改一个方法,而不是改十个。
          这回就要用到createjs的继承api了。
          function Map(){
          this.name = "地图"
          }
          var map = new Map();
          var cls = {};
          (function() {
          function ChinaMap(){
          this.Map_constructor();//构造
          }
          var p = createjs.extend(ChinaMap,Map);//继承
          p.from = "中国";
          p.changeFrom = function (data)
          {
          // p.from = data;//这样就会出错 输出2个美国
          this.from = data;
          }
          cls.ChinaMap = createjs.promote(ChinaMap, "Map");//提升
          }());
          var map1 = new cls.ChinaMap();
          var map2 = new cls.ChinaMap();
          map1.changeFrom("美国");
          console.log(map1.from,map2.from,map1.name,map2.name);
          输出出来是 美国 中国 地图 地图。
          ChinaMap继承了map的属性,所以map1和map2输出name,都能输出Map中的name。这里的createjs.extend相当于,OOP语言里的extend。而我定义的cls相当于是我保存类的一个地方。而这里的p就是继承后对象的原型链,在p中可以定义方法,定义属性,当然在构造中也可以定义方法和属性。
          另外大家也看到了,类里面的方法是不能用原型链来调用方法和修改属性的,因为如果调用所有实例化这个类的对象都会被调用到,所有的属性也都会被修改。
          注意:animteCC调出来的类,继承需要特殊的继承写法,文章结尾介绍。还有,平时写as的童鞋写显示类的时候通常会继承Sprite 而在createjs中可以选择继承Container,千万不要也继承Sprite flash as的sprite和createjs的sprite不是一种东西


          IP属地:浙江5楼2024-10-11 10:33
          回复
            4.提升
            createjs.promote大家可能会觉得陌生,他是createjs特有的处理方法,也是非常聪明的做法,他的作用是“提升”,什么意思呢?其实就是让当前类可以调用其父类爷爷类祖宗类,也就是类名_方法名就可以调用了

            在上面的代码中,大家可以看到,子类虽然重写了父类的方法,但是依然可以调用父类的方法,只需要父类_方法就可以了,当然,只有原型链中的方法,才会被提升。
            很多人会忽视提升的作用,其实提升除了可以调用父类方法,还可以使继承来的属性“合法化”。

            在上面代码中,如果使用上面注释中的代码,检查属性的时候属性就不属于该类本身,原因也很简单,因为这个属性是属于他父类的。(这个问题在很多js框架中都会被忽视,但是createjs却解决了这个问题,说明createjs的团队只是懒,能力还是很强的么^_^)


            IP属地:浙江6楼2024-10-11 10:37
            回复
              5.构造
              构造简单的讲就是类的初始化方法,在js中constructor相当于构造函数,也就是经过上面的代码提升后,this.Map_construtor就是调用父类的构造函数,是写一个类必须的,相当于as3的this.super();


              IP属地:浙江7楼2024-10-11 10:37
              回复
                6.重写
                重写的话,直接在构造或者原型链中重新定义属性或者方法就可以了,但是由于构造中的方法不会被提升,所以重写也尽量在原型链中重写。


                IP属地:浙江8楼2024-10-11 10:37
                回复
                  7.公有私有 js没有 public private protected 等控制属性方法权限的语句,私有方法直接写在闭包内就可以了。

                  注意(一定要看清楚):但是这和一般语言中的私有还是有区别的,一般语言中的私有,你虽然不能用,但是在查看表达式的时候还是看得到的。但是在这里的私有,你在外面是看不到的。所以从架构的角度讲,不要使用上面那种私有。直接在需要私有的属性或方法的命名上写个下划线“_”,程序员之间做个约束,看到带下划线的属性不要去改他就好了。
                  (并且你还要保证类只new一次,不然二次以上私有属性方法就会在各个new出来的对象中污染了,总之这种私有方法不推荐)


                  IP属地:浙江9楼2024-10-11 10:39
                  回复

                    ↑ 封装类必不可少的东西
                    另外还有一个问题,在没有createjs的环境下也能使用这些oop的api吗,答案是可以的,我还特意把相关代码提取了出来,只要把下面的代码放入项目中,不引入createjs,也能使用oop的api
                    this.oop = this.oop||{};
                    oop.extend = function(subclass, superclass) {
                    function o() {
                    this.constructor = subclass;
                    }
                    o.prototype = superclass.prototype;
                    return (subclass.prototype = new o());
                    };
                    oop.promote = function(subclass, prefix) {
                    var subP = subclass.prototype,supP = (Object.getPrototypeOf&&Object.getPrototypeOf(subP))||subP.__proto__;
                    if (supP) {
                    subP[(prefix+="_") + "constructor"] = supP.constructor; // constructor is not always innumerable
                    for (var n in supP) {
                    if (subP.hasOwnProperty(n) && (typeof supP[n] == "function")) { subP[prefix + n] = supP[n]; }
                    }
                    }
                    return subclass;
                    };
                    就这么简单的2个方法……


                    IP属地:浙江10楼2024-10-11 10:45
                    回复
                      最后讲一下,animateCC生成的类怎么继承,直接上代码:
                      var cls = {};
                      cls.MyMc = function MyMc(){
                      this.__proto__ = new lib.mc();
                      }
                      var mc = new cls.MyMc();
                      mc.stop();
                      stage.addChild(mc);
                      大家可以看到由于animateCC生成mc的方式不同,导致我们也只能用类似的方式来继承。


                      IP属地:浙江11楼2024-10-11 10:46
                      回复