mirror of
https://github.com/hiloteam/Hilo.git
synced 2025-12-08 20:35:59 +00:00
171 lines
4.6 KiB
JavaScript
171 lines
4.6 KiB
JavaScript
/**
|
|
* Hilo
|
|
* Copyright 2015 alibaba.com
|
|
* Licensed under the MIT License
|
|
*/
|
|
|
|
/**
|
|
* Create Example Class:
|
|
* <pre>
|
|
* var Bird = Hilo.Class.create({
|
|
* Extends: Animal,
|
|
* Mixes: EventMixin,
|
|
* constructor: function(name){
|
|
* this.name = name;
|
|
* },
|
|
* fly: function(){
|
|
* console.log('I am flying');
|
|
* },
|
|
* Statics: {
|
|
* isBird: function(bird){
|
|
* return bird instanceof Bird;
|
|
* }
|
|
* }
|
|
* });
|
|
*
|
|
* var swallow = new Bird('swallow');
|
|
* swallow.fly();
|
|
* Bird.isBird(swallow);
|
|
* </pre>
|
|
* @namespace Class Class is created to aid the developer.
|
|
* @static
|
|
* @module hilo/core/Class
|
|
*/
|
|
var Class = (function(){
|
|
|
|
/**
|
|
* Create a class based on the parameters, properties and methods specified.
|
|
* @param {Object} properties Properties and methods to create the class.
|
|
* <ul>
|
|
* <li><b>Extends</b> - Designed to inherit the parent class.</li>
|
|
* <li><b>Mixes</b> - Specifies mixed member collection object.</li>
|
|
* <li><b>Statics</b> - Static property or method specified class.</li>
|
|
* <li><b>constructor</b> - The constructor of specified class.</li>
|
|
* <li>Other members of the property or method to create the class.</li>
|
|
* </ul>
|
|
* @returns {Object} Create classes.
|
|
*/
|
|
var create = function(properties){
|
|
properties = properties || {};
|
|
var clazz = properties.hasOwnProperty('constructor') ? properties.constructor : function(){};
|
|
implement.call(clazz, properties);
|
|
return clazz;
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
var implement = function(properties){
|
|
var proto = {}, key, value;
|
|
for(key in properties){
|
|
value = properties[key];
|
|
if(classMutators.hasOwnProperty(key)){
|
|
classMutators[key].call(this, value);
|
|
}else{
|
|
proto[key] = value;
|
|
}
|
|
}
|
|
|
|
mix(this.prototype, proto);
|
|
};
|
|
|
|
var classMutators = /** @ignore */{
|
|
Extends: function(parent){
|
|
var existed = this.prototype, proto = createProto(parent.prototype);
|
|
//inherit static properites
|
|
mix(this, parent);
|
|
//keep existed properties
|
|
mix(proto, existed);
|
|
//correct constructor
|
|
proto.constructor = this;
|
|
//prototype chaining
|
|
this.prototype = proto;
|
|
//shortcut to parent's prototype
|
|
this.superclass = parent.prototype;
|
|
},
|
|
|
|
Mixes: function(items){
|
|
items instanceof Array || (items = [items]);
|
|
var proto = this.prototype, item;
|
|
|
|
while(item = items.shift()){
|
|
mix(proto, item.prototype || item);
|
|
}
|
|
},
|
|
|
|
Statics: function(properties){
|
|
mix(this, properties);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
var createProto = (function(){
|
|
if(Object.__proto__){
|
|
return function(proto){
|
|
return {__proto__: proto};
|
|
};
|
|
}else{
|
|
var Ctor = function(){};
|
|
return function(proto){
|
|
Ctor.prototype = proto;
|
|
return new Ctor();
|
|
};
|
|
}
|
|
})();
|
|
|
|
/**
|
|
* Mixed property or method.
|
|
* @param {Object} target Mixed audiences.
|
|
* @param {Object} source The source whose methods and properties are to be mixed. It can support multiple source parameters.
|
|
* @returns {Object} Mixed audiences.
|
|
*/
|
|
var mix = function(target){
|
|
for(var i = 1, len = arguments.length; i < len; i++){
|
|
var source = arguments[i], defineProps;
|
|
for(var key in source){
|
|
var prop = source[key];
|
|
if(prop && typeof prop === 'object'){
|
|
if(prop.value !== undefined || typeof prop.get === 'function' || typeof prop.set === 'function'){
|
|
defineProps = defineProps || {};
|
|
defineProps[key] = prop;
|
|
continue;
|
|
}
|
|
}
|
|
target[key] = prop;
|
|
}
|
|
if(defineProps) defineProperties(target, defineProps);
|
|
}
|
|
|
|
return target;
|
|
};
|
|
|
|
var defineProperty, defineProperties;
|
|
try{
|
|
defineProperty = Object.defineProperty;
|
|
defineProperties = Object.defineProperties;
|
|
defineProperty({}, '$', {value:0});
|
|
}catch(e){
|
|
if('__defineGetter__' in Object){
|
|
defineProperty = function(obj, prop, desc){
|
|
if('value' in desc) obj[prop] = desc.value;
|
|
if('get' in desc) obj.__defineGetter__(prop, desc.get);
|
|
if('set' in desc) obj.__defineSetter__(prop, desc.set);
|
|
return obj;
|
|
};
|
|
defineProperties = function(obj, props){
|
|
for(var prop in props){
|
|
if(props.hasOwnProperty(prop)){
|
|
defineProperty(obj, prop, props[prop]);
|
|
}
|
|
}
|
|
return obj;
|
|
};
|
|
}
|
|
}
|
|
|
|
return {create:create, mix:mix};
|
|
|
|
})();
|