cocos中类扩展的坑

cocos中类扩展的坑,第1张

概述这个真是坑啊,无语了。 通常在模拟类的实现时,属性是放在实例上,方法是放在原型上,取了节省性能和互不干扰的折中。但是cocos的有点扯。属性也放在了原型上,这就导致了一些问题。 先看重现: // 定义一个新的类var newClass = cc.Class.extend({ prop: 123, ctor: function(){ this.super();

这个真是坑啊,无语了。
通常在模拟类的实现时,属性是放在实例上,方法是放在原型上,取了节省性能和互不干扰的折中。但是cocos的有点扯。属性也放在了原型上,这就导致了一些问题。
先看重现:

// 定义一个新的类var newClass = cc.Class.extend({    prop: 123,ctor: function(){        this.super();        this.prop = 456;        console.log(this.prop);    // 456        this.__proto__.prop)   // 123    }});// 想想,在这里定义prop的时候,下意识是不是认为这是给newClass的实例的?而不是给newClass本身的?

这个坑在平时可能不起眼~看看是怎么发生的:

var ClassA = cc.Class.extend({ arr: [],67)">this.super(); },163)">initthis.arr.push(1); },163)">onExitthis.arr = []; }});// 假设这个对象一直存在,要不停的被复用。var obj1 = new ClassA();obj1.init();// 过一会后obj1.onExit();// 再过一会var obj2 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; y = y; } toString() { return '('+x+','y@H_403_144@')'; }}

属性要求用this.的方式创建。这样属性定义在实例身上,原型自然干净,坑就更少了。

不过cocos采用的貌似是jquery作者提出的继承方案。是当初没有class时模拟class的一个方案。这种定义属性的方式,很容易Js原生开发者产生歧义。

再拿PHP的例子看看,虽然不确定PHP具体细节,但至少执行上看起来是没有歧义的:

Test { public $a array(); function __construct() { }}$obj new Test();array_push($obj->a,"1");"2");"3");var_dump($obj->a); // array(3) { [0]=> string(1) "1" [1]=> string(1) "2" [2]=> string(1) "3" }$obj1 Test();var_dump($obj1// 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中类扩展的坑所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1074562.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存