温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

【cocos2d-x从c++到js】06:Google的继承写法解析

发布时间:2020-04-09 22:03:45 阅读:5660 作者:老G 栏目:游戏开发
C++开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

cocos2d-x for js中集成了两套继承写法,一套是JR的,一套是google。公司同事使用过node.js,对google的继承方式比较赞同。我就看了一下Google的继承代码。

先贴代码:

// 1) Google "subclasses" borrowed from closure library // This is the recommended way to do it // cc.inherits = function (childCtor, parentCtor) {     /** @constructor */     function tempCtor() {};     tempCtor.prototype = parentCtor.prototype;     childCtor.superClass_ = parentCtor.prototype;     childCtor.prototype = new tempCtor();     childCtor.prototype.constructor = childCtor;      // Copy "static" method, but doesn't generate subclasses. //  for( var i in parentCtor ) { //      childCtor[ i ] = parentCtor[ i ]; //  } }; 

cc.inherits是继承函数,负责链接父类和子类的原型链。非常有趣的是,在这里使用了一个临时构造器,这样就替换了JR代码中的initializing 写法。看起来很舒服。

cc.base = function(me, opt_methodName, var_args) {      var caller = arguments.callee.caller;      if (caller.superClass_) {          // This is a constructor. Call the superclass constructor.          ret =  caller.superClass_.constructor.apply( me, Array.prototype.slice.call(arguments, 1));          return ret;      }        var args = Array.prototype.slice.call(arguments, 2);      var foundCaller = false;      for (var ctor = me.constructor;          ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {          if (ctor.prototype[opt_methodName] === caller) {              foundCaller = true;          } else if (foundCaller) {              return ctor.prototype[opt_methodName].apply(me, args);          }      }        // If we did not find the caller in the prototype chain,      // then one of two things happened:      // 1) The caller is an instance method.      // 2) This method was not called by the right caller.      if (me[opt_methodName] === caller) {          return me.constructor.prototype[opt_methodName].apply(me, args);      } else {          throw Error(                      'cc.base called from a method of one name ' +                      'to a method of a different name');      }  };  

cc.base是在子类函数中调用父类同名函数的方法。要使用这个函数,必须是使用过cc.inherits进行过链接原型链的类才行。参数方面,me需要传入this,其他根据形参表来定。

var caller = arguments.callee.caller

首先通过,上面的代码获得外层函数的对象。(据说caller这个属性已经不再建议使用了,不知道是什么原因)。

然后,如果外层函数是构造函数的话,一定是存在superClass_这个属性的。那么可以用apply调用父类的构造器,然后就退出函数执行就可以了。(但是这里为什么会有返回值呢,他喵的构造器返回值不是被运行环境给接管了么?)

    var args = Array.prototype.slice.call(arguments2);       var foundCaller = false;       for (var ctor = me.constructor;           ctor; ctor = ctor.superClass_ && ctor.superClass_.constructor) {           if (ctor.prototype[opt_methodName] === caller) {               foundCaller = true;           } else if (foundCaller) {               return ctor.prototype[opt_methodName].apply(me, args);           }       }   

如果外层函数不是构造函数,那么就是子类的普通函数。后面的代码也很简单,从子类向上往父类上面找,一层一层的遍历构造器,然后再核对同名函数,如果在当前层次找到了对应的函数名,就在下一轮循环中,调用父类的同名函数即可。然后直接返回。

if (me[opt_methodName] === caller) {           return me.constructor.prototype[opt_methodName].apply(me, args);       } else {           throw Error(                       'cc.base called from a method of one name ' +                       'to a method of a different name');       }   

如果要调用的那个函数,既不是构造函数,也不是父类中的同名函数。那么只有一种可能,就是这个函数是子类的一个实例上的函数。直接apply调用就好了。

再找不到的话,代码就会抽风了。(throw Error)

综上,google的代码风格非常流畅,可读性也很高。如果JR是很黄很暴力,各种奇技淫巧不计其数。那么google的代码就是和风细雨,润物细无声。

就我个人而已,非常喜欢JR的接口,但是又喜欢google的内部实现。矛盾啊,喵了个咪。

另外,google的代码可以做到很容易的和其他继承机制兼容,但JR的就不行,必须已自己为核心来搞才可以的。这些是由他们的实现机制决定的。

目前来说,cocos2d-x for js使用JR的写法,不知道会不会对将来的扩展造成一些问题呢。

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×