cocos中类扩展的坑
来源:互联网 发布:虚拟定位是什么软件 编辑:程序博客网 时间:2024/06/09 22:57
这个真是坑啊,无语了。
通常在模拟类的实现时,属性是放在实例上,方法是放在原型上,取了节省性能和互不干扰的折中。但是cocos的有点扯。属性也放在了原型上,这就导致了一些问题。
先看重现:
// 定义一个新的类var newClass = cc.Class.extend({ prop: 123, ctor: function(){ this.super(); this.prop = 456; console.log(this.prop); // 456 console.log(this.__proto__.prop) // 123 }});// 想想,在这里定义prop的时候,下意识是不是认为这是给newClass的实例的?而不是给newClass本身的?
这个坑在平时可能不起眼~看看是怎么发生的:
var ClassA = cc.Class.extend({ arr: [], ctor: function(){ this.super(); }, init: function(){ this.arr.push(1); }, onExit: function(){ this.arr = []; }});// 假设这个对象一直存在,要不停的被复用。var obj1 = new ClassA();obj1.init();// 过一会后obj1.onExit();// 再过一会var obj2 = new ClassA();obj2.init();// 此时输出`obj2.arr`会发现是`[1, 1]`,而不是期望的`[1]`
尽管我们在onExit时释放了this.arr,让他等于一个新数组。但原型上的arr仍然存在。当实例一个新的对象obj2时,obj2.arr访问的仍然是原型上的arr,结果就变成了[1, 1]
。
可能会认为在ctor中初始化一下this.arr = []
不就结了,实际上ES6的class就是这么要求的。cocos为我们提供的这个类扩展方式,很容易产生歧义。
看看ES6的class规范如何定义属性:
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '('+this.x+', '+this.y+')'; }}
属性要求用this.
的方式创建。这样属性定义在实例身上,原型自然干净,坑就更少了。
不过cocos采用的貌似是jQuery作者提出的继承方案。是当初没有class时模拟class的一个方案。这种定义属性的方式,很容易JS原生开发者产生歧义。
再拿PHP的例子看看,虽然不确定PHP具体细节,但至少执行上看起来是没有歧义的:
class Test { public $a = array(); function __construct() { }}$obj = new Test();array_push($obj->a, "1");array_push($obj->a, "2");array_push($obj->a, "3");var_dump($obj->a); // array(3) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" }$obj1 = new Test();var_dump($obj1->a); // array(0) { }
可以看到obj1对属性a的修改并没有影响到obj2的属性a。但是翻译到cocos的extend,就会出现最上面提到的问题。所以要么就完整的支持 类似PHP这种 直接定义属性 的方式,要么就像ES6的class一样,不支持,只允许this.
方式创建属性。
不吐槽了。
结论
属性放在ctor函数内进行用this.prop = value
形式声明。
是的,因为这个,我们遇到严重的内存泄露了。
参考文档
ES6中文学习文档 http://es6.ruanyifeng.com/#docs/class
- cocos中类扩展的坑
- cocos creator 中数据储存的坑。。。
- cocos中Widget 的用法
- Cocos中动作的初识
- cocos clone 的坑
- cocos--类的创建
- Cocos Studio 扩展说明
- Cocos-2d中各个类之间的结构…
- 在cocos引擎中封装的集合类Vector
- cocos creator下载扩展商店里的源码
- cocos-2d中CCUserDefault的使用
- Cocos中有关九宫格的解释
- quick-cocos中定时器的使用
- cocos中Action的基本使用
- 7.21:对Cocos中精灵的理解
- 学习Cocos的第一步,认识Cocos中的Ref类
- C#中扩展类和扩展方法的使用
- cocos2d-js研究:cocos工具生成的项目移植到cocos code ide 中
- cocoapods参考
- SSH项目部署weblogic遇到的问题总结
- 【Android】 LayoutInflater和SetContentView详解
- 大学见闻
- android 计算listview的高度
- cocos中类扩展的坑
- 在使用CommonComplexAdapter时遇到的类型无法转换问题
- centos把用户加入sudoers
- 深入浅出 Java 8 Lambda 表达式
- Android优秀文章链接
- Spring事务配置的五种方式
- Spring Mybatis log4j 在日志文件中显示sql日志
- Ubuntu下的抓包工具tcpdump
- UIButton 设置图片显示 contentmode