主要包含 CCEnum.js id-generater.js js.js
CCEnum.js
Enum 作用是用来创建一个枚举类型.基本使用:
let Dir = cc.Enum({Up:-1,Down:-1,Left:-1,Right:-1});
则 Dir.Up = 0, Dir.Down = 1, Dir.Left = 2, Dir.Right = 3;
id-generater.js
IdGenerater 用来产生id, getNewId 方法会递增 id.
js.js
function _getPropertyDescriptor (obj, name) {
while (obj) {
var pd = Object.getOwnPropertyDescriptor(obj, name);
if (pd) {
return pd;
}
obj = Object.getPrototypeOf(obj);
}
return null;
}
此方法获取 obj 对象上 name 属性的描述. 如果对象本身不包含name属性,则会检查原型链.
function _copyprop(name, source, target) {
var pd = _getPropertyDescriptor(source, name);
Object.defineProperty(target, name, pd);
}
此方法会,将 source上name所表示的属性,复制到target对象上.
js 对象上包含了一些通用的方法:
// Copy all properties not defined in obj from arguments[1...n]
addon: function (obj) {
'use strict';
obj = obj || {};
for (var i = 1, length = arguments.length; i < length; i++) {
var source = arguments[i];
if (source) {
if (typeof source !== 'object') {
cc.errorID(5402, source);
continue;
}
for ( var name in source) {
if ( !(name in obj) ) {
_copyprop( name, source, obj);
}
}
}
}
return obj;
},
如:
let obj = {name:'obj'};
js.addon(obj,{name:'zhangsan',age:12},{weight:22});
// obj 会有 name age weight,属性. 但是name属性不会被覆盖
mixin
和 addon方式类似,但是会覆盖原来的对象的属性.extend (cls, base)
实现 原型链 继承. cls 继承 base.getSuper (ctor)
获取 ctor的 父类的构造函数isChildClassOf (subclass, superclass)
检查 subclass 是否是 superclass 的子类.clear (obj)
删除 clear 自身上的 所有属性.isEmptyObject (obj)
判断是否是空对象.js.value (obj, prop, value, writable, enumerable)
设置对象obj的属性prop的描述js.getset(obj, prop, getter, setter, enumerable, configurable)
设置对象 obj 的 prop 属性的 get set 描述js.get/set(obj, prop, getter, enumerable, configurable)
设置对象 obj 的 prop 属性的 get/set 描述js.getClassName (objOrCtor)
Get class name of the object, if object is just a {} (and which class named 'Object'), it will return "".
获取 objOrCtor 的类名.- id 注册.
// id 注册
(function () {
var _idToClass = {};
var _nameToClass = {};
function setup (key, publicName, table) {
js.getset(js, publicName,
function () {
return Object.assign({}, table);
},
function (value) {
js.clear(table);
Object.assign(table, value);
}
);
return function (id, constructor) {
// deregister old
if (constructor.prototype.hasOwnProperty(key)) {
delete table[constructor.prototype[key]];
}
js.value(constructor.prototype, key, id);
// register class
if (id) {
var registered = table[id];
if (registered && registered !== constructor) {
var error = 'A Class already exists with the same ' + key + ' : "' + id + '".';
if (CC_TEST) {
error += ' (This may be caused by error of unit test.) \
If you dont need serialization, you can set class id to "". You can also call \
cc.js.unregisterClass to remove the id of unused class';
}
cc.error(error);
}
else {
table[id] = constructor;
}
//if (id === "") {
// console.trace("", table === _nameToClass);
//}
}
};
}
/**
* Register the class by specified id, if its classname is not defined, the class name will also be set.
* @method _setClassId
* @param {String} classId
* @param {Function} constructor
* @private
*/
/**
* !#en All classes registered in the engine, indexed by ID.
* !#zh 引擎中已注册的所有类型,通过 ID 进行索引。
* @property _registeredClassIds
* @example
* // save all registered classes before loading scripts
* let builtinClassIds = cc.js._registeredClassIds;
* let builtinClassNames = cc.js._registeredClassNames;
* // load some scripts that contain CCClass
* ...
* // clear all loaded classes
* cc.js._registeredClassIds = builtinClassIds;
* cc.js._registeredClassNames = builtinClassNames;
*/
js._setClassId = setup('__cid__', '_registeredClassIds', _idToClass);
/**
* !#en All classes registered in the engine, indexed by name.
* !#zh 引擎中已注册的所有类型,通过名称进行索引。
* @property _registeredClassNames
* @example
* // save all registered classes before loading scripts
* let builtinClassIds = cc.js._registeredClassIds;
* let builtinClassNames = cc.js._registeredClassNames;
* // load some scripts that contain CCClass
* ...
* // clear all loaded classes
* cc.js._registeredClassIds = builtinClassIds;
* cc.js._registeredClassNames = builtinClassNames;
*/
var doSetClassName = setup('__classname__', '_registeredClassNames', _nameToClass);
/**
* Register the class by specified name manually
* @method setClassName
* @param {String} className
* @param {Function} constructor
*/
js.setClassName = function (className, constructor) {
doSetClassName(className, constructor);
// auto set class id
if (!constructor.prototype.hasOwnProperty('__cid__')) {
var id = className || tempCIDGenerater.getNewId();
if (id) {
js._setClassId(id, constructor);
}
}
};
/**
* Unregister a class from fireball.
*
* If you dont need a registered class anymore, you should unregister the class so that Fireball will not keep its reference anymore.
* Please note that its still your responsibility to free other references to the class.
*
* @method unregisterClass
* @param {Function} ...constructor - the class you will want to unregister, any number of classes can be added
*/
js.unregisterClass = function () {
for (var i = 0; i < arguments.length; i++) {
var p = arguments[i].prototype;
var classId = p.__cid__;
if (classId) {
delete _idToClass[classId];
}
var classname = p.__classname__;
if (classname) {
delete _nameToClass[classname];
}
}
};
/**
* Get the registered class by id
* @method _getClassById
* @param {String} classId
* @return {Function} constructor
* @private
*/
js._getClassById = function (classId) {
return _idToClass[classId];
};
/**
* Get the registered class by name
* @method getClassByName
* @param {String} classname
* @return {Function} constructor
*/
js.getClassByName = function (classname) {
return _nameToClass[classname];
};
/**
* Get class id of the object
* @method _getClassId
* @param {Object|Function} obj - instance or constructor
* @param {Boolean} [allowTempId=true] - can return temp id in editor
* @return {String}
* @private
*/
js._getClassId = function (obj, allowTempId) {
allowTempId = (typeof allowTempId !== 'undefined' ? allowTempId: true);
var res;
if (typeof obj === 'function' && obj.prototype.hasOwnProperty('__cid__')) {
res = obj.prototype.__cid__;
if (!allowTempId && (CC_DEV || CC_EDITOR) && isTempClassId(res)) {
return '';
}
return res;
}
if (obj && obj.constructor) {
var prototype = obj.constructor.prototype;
if (prototype && prototype.hasOwnProperty('__cid__')) {
res = obj.__cid__;
if (!allowTempId && (CC_DEV || CC_EDITOR) && isTempClassId(res)) {
return '';
}
return res;
}
}
return '';
};
})();
/**
1. js.setClassName(className, constructor)
通过给 constructor.prototype 添加 __classname__ 属性,
再 使用 className 作为key,constructor 作为value,
存放在 _registeredClassNames 这个对象中.
然后,检查 constructor.prototype 的 __cid__ 这个属性, 通过 __cid__ 的值(如果不存在,则会生成一个)作为key,
constructor 做为value,存放在 _registeredClassNames 这个对象中.
2. js.unregisterClass
就是 删除 已经注册的 constructor, 会删除 constructor.prototype 上的 __classname__ 和 __cid__ 属性.
3. 其他的方法就是根据 id 或者 classname,去查找存放的 constructor.
**/
js.obsolete (obj, obsoleted, newExpr, writable)
相当于使用 newExpr属性 代替原来的 obsoleted 属性.- js.formatStr
如:
cc.js.formatStr("a: %s, b: %s", a, b);
返回格式化字符串.
js.shiftArguments
返回 从第2个参数开始的数组. 相当于 Array.prototype.slice.call(arguments,1)js.createMap
相当于 Object.create(null)removeAt (array, index)
删除 array中 所以为 index 的元素fastRemoveAt (array, index)
直接使用 最后一个元素替换掉 index位置的元素,然后length减1.remove (array, value)
删除 array 中,第一个值为 value 的元素. 如果存在 返回true,否则返回 falsefastRemove (array, value)
类似 fastRemoveAtverifyType (array, type)
验证 array 中的元素 是否都是 type 类型. 如果都是 则返回true,否则返回 false.removeArray (array, minusArr)
从 array 中删除 minusArr数组中的 值.- appendObjectsAt (array, addObjs, index)
如:
var arr = [1,2,3,4,5];
appendObjectsAt(arr,[7,8,9],1);
console.log(arr); // [ 1, 7, 8, 9, 2, 3, 4, 5 ]
contains (array, value)
array 中 是否包含 value. 包含返回 true,否则返回 falsecopy (array)
返回 array 的一个副本.(浅拷贝)- js.Pool
注意:对象池刚创建的时候,当前可用的对象数量是0.
Pool对象主要需要包含几个方法:
a. get 方法. 这个需要使用的用户 自己实现.
b. _get 方法,会检查当前对象池中是否有可用的对象. 如果有,则返回一个可用的对象,否则返回null
c. put 方法. 把一个不在需要的对象放回对象池.池中可用的对象会加1
d. resize 方法. 会增大/减少对象池的大小.
自带的两个使用 Pool 的例子:
/*
*Example 1:
*
*function Details () {
* this.uuidList = [];
*};
*Details.prototype.reset = function () {
* this.uuidList.length = 0;
*};
*Details.pool = new js.Pool(function (obj) {
* obj.reset();
*}, 5);
*Details.pool.get = function () {
* return this._get() || new Details();
*};
*
*var detail = Details.pool.get();
*...
*Details.pool.put(detail);
*
*Example 2:
*
*function Details (buffer) {
* this.uuidList = buffer;
*};
*...
*Details.pool.get = function (buffer) {
* var cached = this._get();
* if (cached) {
* cached.uuidList = buffer;
* return cached;
* }
* else {
* return new Details(buffer);
* }
*};
*
*var detail = Details.pool.get( [] );
*/