cocos中類擴充套件的坑

2021-07-07 06:18:33 字數 1807 閱讀 8020

這個真是坑啊,無語了。

通常在模擬類的實現時,屬性是放在例項上,方法是放在原型上,取了節省效能和互不干擾的折中。但是cocos的有點扯。屬性也放在了原型上,這就導致了一些問題。

先看重現:

// 定義乙個新的類

var newclass = cc.class.extend(

});// 想想,在這裡定義prop的時候,下意識是不是認為這是給newclass的例項的?而不是給newclass本身的?

這個坑在平時可能不起眼~看看是怎麼發生的:

var classa = cc.class.extend(,

init

:function(),

onexit

:function()

});// 假設這個物件一直存在,要不停的被復用。

var obj1 =

newclassa();

obj1.init();

// 過一會後

obj1.onexit();

// 再過一會

var obj2 =

newclassa();

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

tostring()

}

屬性要求用this.的方式建立。這樣屬性定義在例項身上,原型自然乾淨,坑就更少了。

不過cocos採用的貌似是jquery作者提出的繼承方案。是當初沒有class時模擬class的乙個方案。這種定義屬性的方式,很容易js原生開發者產生歧義。

再拿php的例子看看,雖然不確定php具體細節,但至少執行上看起來是沒有歧義的:

class

test

}$obj

=new

test();

array_push($obj

->

a, "1"

);array_push($obj

->

a, "2"

);array_push($obj

->

a, "3"

);var_dump($obj

->

a); // array(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中文學習文件 

Cocos 踩過的坑

有些小坑和解決方案,想記錄下來 0.一些有用的 easing緩衝動畫 3d網格動畫 1.防止點選穿透 場景 在遊戲介面有功能按鈕,上層彈出layer之後,加入了遮罩,但是遊戲介面的功能按鈕還可以點選,穿透了!方案1 開啟遮罩的互動性 interactable node.settouchenable ...

Calendar類set方法中的坑

在仔細一查發現工具類中有乙個獲取月份最大值,問題就出現在這裡咯。很簡單 public static int lastday int month 然後我發現無論傳什麼進去最大值都是31。在system.out.println calendar.gettime 列印出當前時間看看。發現如果傳進去的月份有...

php require 在類的繼承中的坑

對於php的檔案呼叫,我們有時會為使用include,include once,require,require once而陷入斟酌,不僅初學者如此,高階工程是由也會有糾結的時候。而且至今使用哪乙個為最優仍沒有達成共識。每個團隊每個專案有自己的 規範,也有自己的使用理由。至於四個函式的異同,在此不作贅...