类的使用和面向对象

大家都知道在cocos2d-x 底层是C++编写的,那么就有类的概念和继承机制。

但是在JS中,是没有类这个概念的,没有提供类,没有C++的类继承机制。

那么JS是通过什么方式实现简单的继承呢?JS是通过对象的原型实现继承。

我们来看一下这段代码:

var baselayer = cc.Layer.extend({ctor:function(){this._super();cc.log("baselayer ctor read");},init:function(){this._super();cc.log("baselayer init read");}
});

我们申明了baseLayer对象 ,并且利用cc.Layer.extend,继承了CClayer。

那么问题来了?他究竟是怎么实现的呢?我们按住crtl跟进去看看cc.Layer.extend的实现;

ClassManager.compileSuper.ClassManager = ClassManager;/* Managed JavaScript Inheritance* Based on John Resig's Simple JavaScript Inheritance http://ejohn.org/blog/simple-javascript-inheritance/* MIT Licensed.* 在这里申明了,实现JS继承的方式 是参考了 John Resig's  的一个例子来实现的;并且有原文地址,有兴趣的同学可以去看看原版实现方式*/
(function () {var fnTest = /\b_super\b/;var config = cc.game.config;var releaseMode = config[cc.game.CONFIG_KEY.classReleaseMode];if(releaseMode) {console.log("release Mode");}/*** The base Class implementation (does nothing)* @class*/cc.Class = function () {};/*** Create a new Class that inherits from this Class* @static* @param {object} props* @return {function}*/cc.Class.extend = function (props) {//声明_super对象,并赋值为原型var _super = this.prototype;// Instantiate a base Class (but only create the instance,// don't run the init constructor)//实例化创建prototype这个基类,只是创建实例,并没有跑init构造函数var prototype = Object.create(_super);//给这个class复制ID标识,并且将_super对象添加到ClassManager类管理器中var classId = ClassManager.getNewID();ClassManager[classId] = _super;// Copy the properties over onto the new prototype. We make function// properties non-eumerable as this makes typeof === 'function' check// unneccessary in the for...in loop used 1) for generating Class()// 2) for cc.clone and perhaps more. It is also required to make// these function properties cacheable in Carakan.//进行函数的验证检测,以及设置他使用基本设置var desc = { writable: true, enumerable: false, configurable: true };//单例模式的基础申明prototype.__instanceId = null;// The dummy Class constructor//创建Class这个类function Class() {this.__instanceId = ClassManager.getNewInstanceId();// All construction is actually done in the init method//如果这个类他存在.ctor方法,那么就默认的使用执行这个方法//ctor在JS中就相当于构造函数if (this.ctor)this.ctor.apply(this, arguments);}//给ID复制Class.id = classId;// desc = { writable: true, enumerable: false, configurable: true,//          value: XXX }; Again, we make this non-enumerable.desc.value = classId;Object.defineProperty(prototype, '__pid', desc);// Populate our constructed prototype object//把我们原型对象赋值Class.prototype = prototype;// Enforce the constructor to be what we expect//将整个类赋值给desc.valuedesc.value = Class;//并且将类里构造的对象赋值Object.defineProperty(Class.prototype, 'constructor', desc);// Copy getter/setter//模拟get/set的方式,使用cc.clone函数来拷贝this.__getters__ && (Class.__getters__ = cc.clone(this.__getters__));this.__setters__ && (Class.__setters__ = cc.clone(this.__setters__));for(var idx = 0, li = arguments.length; idx < li; ++idx) {var prop = arguments[idx];for (var name in prop) {var isFunc = (typeof prop[name] === "function");var override = (typeof _super[name] === "function");var hasSuperCall = fnTest.test(prop[name]);if (releaseMode && isFunc && override && hasSuperCall) {desc.value = ClassManager.compileSuper(prop[name], name, classId);Object.defineProperty(prototype, name, desc);} else if (isFunc && override && hasSuperCall) {desc.value = (function (name, fn) {return function () {var tmp = this._super;// Add a new ._super() method that is the same method// but on the super-Class//如果在新的对象方法里面添加._super(),他会继承父类的_super方法//并且实现方法里面的所有对象及方法的赋值this._super = _super[name];// The method only need to be bound temporarily, so we// remove it when we're done executingvar ret = fn.apply(this, arguments);this._super = tmp;return ret;};})(name, prop[name]);Object.defineProperty(prototype, name, desc);} else if (isFunc) {desc.value = prop[name];Object.defineProperty(prototype, name, desc);} else {prototype[name] = prop[name];}if (isFunc) {// Override registered getter/setter//如果是方法,那么重载里面的属性,并且实现get,set方法可以直接使用var getter, setter, propertyName;if (this.__getters__ && this.__getters__[name]) {propertyName = this.__getters__[name];for (var i in this.__setters__) {if (this.__setters__[i] === propertyName) {setter = i;break;}}cc.defineGetterSetter(prototype, propertyName, prop[name], prop[setter] ? prop[setter] : prototype[setter], name, setter);}if (this.__setters__ && this.__setters__[name]) {propertyName = this.__setters__[name];for (var i in this.__getters__) {if (this.__getters__[i] === propertyName) {getter = i;break;}}cc.defineGetterSetter(prototype, propertyName, prop[getter] ? prop[getter] : prototype[getter], prop[name], getter, name);}}}}// And make this Class extendable// 可以使用Class.extend来实现类的继承Class.extend = cc.Class.extend;//add implementation method//添加要实现的方法Class.implement = function (prop) {for (var name in prop) {prototype[name] = prop[name];}};return Class;};
})();

View Code

重点看3个点:

        // The dummy Class constructor//创建Class这个类function Class() {this.__instanceId = ClassManager.getNewInstanceId();// All construction is actually done in the init method//如果这个类他存在.ctor方法,那么就默认的使用执行这个方法//ctor在JS中就相当于构造函数if (this.ctor)this.ctor.apply(this, arguments);}    

第一,这个是在JS中的实现构造函数的方法,如果在自定义类中,存在有ctor:function()这个方法,那么他会

默认执行,默认成为构造函数;

                desc.value = (function (name, fn) {return function () {var tmp = this._super;// Add a new ._super() method that is the same method// but on the super-Class//如果在新的对象方法里面添加._super(),他会继承父类的_super方法//并且实现方法里面的所有对象及方法的赋值this._super = _super[name];// The method only need to be bound temporarily, so we// remove it when we're done executingvar ret = fn.apply(this, arguments);this._super = tmp;return ret;};})(name, prop[name]);            

第二,desc.value在这个for循环中的赋值,实现了this._super()的原理,它会为派生类实完成对父类的实现;

通俗点来说,就是,如果我们想要继承并实现父类的方法,那么就需要在方法里面调用this._super()这个方法!

        // And make this Class extendable// 可以使用Class.extend来实现类的继承Class.extend = cc.Class.extend;    

第三,讲cc.Class.extend赋值给Class.extend,就可以使用Class.extend来实现自定义类的继承;

OK,梳理完毕下面看看我们来学习一下怎么实现自定义类和自定义的继承:

var myLayer = baselayer.extend({ctor:function(){this._super();cc.log("myLayer ctor read");},init:function(){this._super();cc.log("myLayer init read");}
});

这段代码中我从myLayer继承了父类baselayer,注意用法就是刚才我们Review底层代码时看到的

var myLayer = baselayer.extend({});

然后继续续实现ctor构造方法函数,和自定义方法函数init;

并且日志输出一下;

最终我们需要在MainScene中调用;

如下:

var MainScene = cc.Scene.extend({onEnter:function(){this._super();var layer = new myLayer();this.addChild(layer);}
});

我们首先只调用

var layer = new myLayer();

看看最终输出是什么?

从输出可以看出他先调用了baselayer,再调用了myLayer;

那么就可以理解为我们直接new myLayer() 会直接自动实现调用我们写的ctor构造函数方法;

而且是先调用父类,然后再调用我们的派生类自定义类;

他并没有主动调用init:function()这个方法,因为他是我们自定义的,所以需要我们手动去调用

 layer.init();

OK,我们加上手动调用后再来看一下输出是什么?

我们可以看到了前两行输出都是 ctor 先执行;

init 函数后执行;

而且调用也是 先执行baseLayer 我们的父类的init函数 再执行我们的自定义init方法!

现在就非常清晰了,我们的myLayer.init方法继承了baseLayer.init的属性方法;

而且实现的原理就是通过this._super()来实现的!

我们再修改一下代码来看看是不是这样,将myLayer类里面的init方法里面的this._super();这句话去掉!

看看我们的baseLayer.init方法会不会被调用

var myLayer = baselayer.extend({ctor:function(){this._super();cc.log("myLayer ctor read");},init:function(){cc.log("myLayer init read");}
});

看看输出:

从输出看出,并没有执行baseLayer 的init方法函数,那么也就验证了this._super();的作用;
this._super()调用实现了对父类的继承,包括父类相同名方法里面的参数的继承;
这段很精辟的代码就大概介绍了 在cocos2dx-Js中如何实现类,和类的继承的概念;
有了面向对象的编程概念后我们以后在cocos2dx-Js中,实现更复杂的逻辑实现和功能实现就变得非常容易了!
本教程结束;
本教程视地址频在:
九秒课堂 
想通过视频学习本教程的童鞋可以进入九秒课堂观看本章节视频;

【Cocos2d-Js基础教学(2)类的使用和面向对象】相关推荐

  1. JS基础-Java Class类以及获取Class实例的三种方式

    JS基础-Java Class类以及获取Class实例的三种方式 由于JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名.包名.父类.实现的接口. ...

  2. web前端基础教学视频分享(一)html+css+js基础教学(附淘宝网站开发教程)

    路漫漫其修远兮 吾将上下而求索 路很长,未来是你们的!献给每位正在奋斗的孩纸们. [写在前面]15年刚接触前端的时候,觉得很有魅力,就好像自己能够控制整个世界似的. 那个时候也不知道怎么学习怎么入门, ...

  3. JavaScript入门,js基础教学

    JS入门 js的书写位置 内嵌式 使用的是Script标签,该标签可以写在html文档中的任何位置 [强调]一般情况下,我们应该将其写在head标签中. 外链式 通过script标签的src属性,引入 ...

  4. 前端工程师面试问题归纳(一、问答类html/css/js基础)

    一.参考资源 1.前端面试题及答案整理(一) 2.2017年前端面试题整理汇总100题 3.2018最新Web前端经典面试试题及答案 4.[javascript常见面试题]常见前端面试题及答案 5.W ...

  5. 计算机类与财经结合,财经类专业计算机基础教学模式分析与探讨

    中图分类号:G642 文献标识:A 文章编号:1009-4202(2012)09-000-01 摘 要 本文结合财经类专业计算机基础教育的实际要求,分析探讨适合财经类专业计算机基础教学的新模式.要求计 ...

  6. 【Cocos2d-Js基础教学 入门目录】

    本教程视地址频在: 九秒课堂 完全免费 从接触Cocos2dx-Js以来,它的绽放的绚丽让我无法不对它喜欢.我觉得Js在不断带给我们惊喜:在开发过程中,会大大提升我们对原型开发的利用率,使用Js语言做 ...

  7. JS基础知识学习(一)

    JS基础知识 前端开发常用的浏览器 谷歌浏览器(chrome):Webkit内核(v8引擎) 火狐浏览器(firefox):Gecko内核 欧朋浏览器(opera):Presto内核 IE浏览器:Tr ...

  8. 前端面试题目汇总摘录(JS 基础篇 —— 2018.11.01更新)

    温故而知新,保持空杯心态 JS 基础 JavaScript 的 typeof 返回那些数据类型 object number function boolean undefined string type ...

  9. JS基础篇--HTML DOM classList 属性

    页面DOM里的每个节点上都有一个classList对象,程序员可以使用里面的方法新增.删除.修改节点上的CSS类.使用classList,程序员还可以用它来判断某个节点是否被赋予了某个CSS类. 添加 ...

  10. python爬虫入门-python爬虫入门,8分钟就够了,最简单的基础教学!

    一.基础入门 1.1什么是爬虫 爬虫(spider,又网络爬虫),是指向网站/网络发起请求,获取资源后分析并提取有用数据的程序. 从技术层面来说就是 通过程序模拟浏览器请求站点的行为,把站点返回的HT ...

最新文章

  1. 重构广义应用数学:人工智能,数学发展的重大机遇
  2. python语言程序设计——深入学习python
  3. Mac OSX Versions输入username按1下都会出现2个字符,并且不能create,解决方法
  4. 机器学习的练功心法(一)——机器学习概述
  5. 重写laravel的request的校验器
  6. Python语言中 del函数和insert函数用法
  7. 完美解决Python套接字编程时TCP断包与粘包问题
  8. 编译原理_P1001
  9. python if条件判断语句
  10. linux离线安装yum源
  11. Windows与Linux的UEFI引导修复教程
  12. quartz之动态定时器实现
  13. PROE 安装提示注册号丢失
  14. C/C++ 根据年月日计算星期几——蔡勒公式篇
  15. win10 电脑触摸板不能滑动_win10系统笔记本触摸板只能移动鼠标不能点击使用的处理办法...
  16. pandas绘图plot函数
  17. J2SDK和TOMCAT的安装及配置
  18. AlexNet(Pytorch实现)
  19. 2018秋季寒假作业2-记叙在人生路上对我影响最大的三位老师
  20. 湖北省专科计算机竞赛,NOI信息学竞赛2019年湖北省队名单

热门文章

  1. 获取C#代码执行的时间(精确到毫秒)
  2. xcode 4.2 开发2——TabelView
  3. JVM第三节:垃圾回收算法与垃圾回收器
  4. 106 网络编程实战之基于socketserver实现多用户FTP服务器
  5. Python连载7-time包的其他函数
  6. MySQL学习十四创建和操纵表
  7. Sublime Text 2 常用插件介绍
  8. HTTPS 使用certbot升级过期证书
  9. [译]应用内搜索功能实现 Android TV应用程序手册教程十三
  10. win下MySQL 8.0.11 修改密码、开启远程访问