這個真是坑啊,無語了。
通常在模擬類的實現時,屬性是放在例項上,方法是放在原型上,取了節省效能和互不干擾的折中。但是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規範如何定義屬性:
classpoint
tostring()
}
屬性要求用this.
的方式建立。這樣屬性定義在例項身上,原型自然乾淨,坑就更少了。
不過cocos採用的貌似是jquery作者提出的繼承方案。是當初沒有class時模擬class的乙個方案。這種定義屬性的方式,很容易js原生開發者產生歧義。
再拿php的例子看看,雖然不確定php具體細節,但至少執行上看起來是沒有歧義的:
classtest
}$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而陷入斟酌,不僅初學者如此,高階工程是由也會有糾結的時候。而且至今使用哪乙個為最優仍沒有達成共識。每個團隊每個專案有自己的 規範,也有自己的使用理由。至於四個函式的異同,在此不作贅...