Created
July 8, 2016 09:32
-
-
Save fwon/d4df8be3ddf7b5c0601ee795b3015e0b to your computer and use it in GitHub Desktop.
Hilo 中的 Class类
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Hilo | |
* Copyright 2015 alibaba.com | |
* Licensed under the MIT License | |
*/ | |
/** | |
* @language=en | |
* 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 | |
*/ | |
/** | |
* @language=zh | |
* 创建类示例: | |
* <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是提供类的创建的辅助工具。 | |
* @static | |
* @module hilo/core/Class | |
*/ | |
var Class = (function(){ | |
/** | |
* @language=en | |
* 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. | |
*/ | |
/** | |
* @language=zh | |
* 根据参数指定的属性和方法创建类。 | |
* @param {Object} properties 要创建的类的相关属性和方法。主要有: | |
* <ul> | |
* <li><b>Extends</b> - 指定要继承的父类。</li> | |
* <li><b>Mixes</b> - 指定要混入的成员集合对象。</li> | |
* <li><b>Statics</b> - 指定类的静态属性或方法。</li> | |
* <li><b>constructor</b> - 指定类的构造函数。</li> | |
* <li>其他创建类的成员属性或方法。</li> | |
* </ul> | |
* @returns {Object} 创建的类。 | |
*/ | |
var create = function(properties){ | |
properties = properties || {}; | |
var clazz = properties.hasOwnProperty('constructor') ? properties.constructor : function(){}; | |
implement.call(clazz, properties); | |
return clazz; | |
} | |
/** | |
* @language=en | |
* @private | |
*/ | |
/** | |
* @language=zh | |
* @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); | |
} | |
}; | |
/** | |
* @language=en | |
* @private | |
*/ | |
/** | |
* @language=zh | |
* @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(); | |
} | |
} | |
})(); | |
/** | |
* @language=en | |
* 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. | |
*/ | |
/** | |
* @language=zh | |
* 混入属性或方法。 | |
* @param {Object} target 混入目标对象。 | |
* @param {Object} source 要混入的属性和方法来源。可支持多个来源参数。 | |
* @returns {Object} 混入目标对象。 | |
*/ | |
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; | |
}; | |
try{ | |
var 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}; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment