Arale Class基类源码解析

来源:互联网 发布:嵌入式软件 就是嵌软吗 编辑:程序博客网 时间:2024/06/16 11:59

JS中OO的模拟有很多的实现与尝试(相关文章),Arale则在以下原则的指导下进行构建:

1.如无必要,勿增实体 —— Simple
2. 一目了然,容易学习 —— Stupid

Class源码的学习可以通过了解如何调用Class来实现类的继承与扩展的例子进行学习。下面是对Class类的源码的注释(简单的辅助方法不再进行注释),有问题可指出,欢迎交流。

// The base Class implementation.// 基本的Class类的构造函数// --直接调用该构造函数,传入的类o将被包裹,拥有extend和implement方法。function Class(o) {// Convert existed function to Class.if (!(this instanceof Class) && isFunction(o)) {return classify(o)}}// commonJS规范module.exports = Class// Create a new Class.//// var SuperPig = Class.create({// Extends: Animal,// Implements: Flyable,// initialize: function() {// SuperPig.superclass.initialize.apply(this, arguments)// },// Statics: {// COLOR: 'red'// }// })// 核心方法,返回一个新创建的子类// --如果传入了父类parent以及传递给子类原型的properties对象,则分别继承父类的实例方法以及静态属性// --如果只传入了properties对象,则默认将parent置为该对象的Extends属性值,没有该属性则默认置为ClassClass.create = function(parent, properties) {// 强制parent为函数类型,properties(最好)为对象if (!isFunction(parent)) {properties = parentparent = null}properties || (properties = {}) // 防报错,默认置为空对象parent || (parent = properties.Extends || Class)// Subclass需要继承的父类properties.Extends = parent //将父类置为properties的Extends属性值(可参考上面调用Class.create的例子)// The created class constructor// 创建类的构造函数function SubClass() {// 调用父类的构造函数,继承其中的实例方法parent.apply(this, arguments)// 在构造函数为Subclass自身且具有initialize实例方法的时候执行初始化方法if (this.constructor === SubClass && this.initialize) {this.initialize.apply(this, arguments)}}// Inherit class (static) properties from parent.// 将父类的静态方法mix给Subclass(可在父类StaticsWhiteList属性中指定要继承的属性)if (parent !== Class) {mix(SubClass, parent, parent.StaticsWhiteList)}// Add instance properties to the subclass.// 该方法特别重要。遍历properties的所有属性,如果该属性名存在于Class.Mutators中(Extends,Implements,Statics),// 则执行Class.Mutators对应的方法,否则将该属性对应的值赋给Subclass的原型链作为其实例属性// 因此,Class.Mutators的所有方法中的this指向Subclass,这一点需要注意implement.call(SubClass, properties)// Make subclass extendable.类化Subclass,使其可扩展可继承其他类return classify(SubClass)}function implement(properties) {var key, valuefor (key in properties) {value = properties[key]if (Class.Mutators.hasOwnProperty(key)) {Class.Mutators[key].call(this, value)} else {this.prototype[key] = value}}}// Create a sub Class based on `Class`.// 基于Class创建子类Class.extend = function(properties) {properties || (properties = {})properties.Extends = thisreturn Class.create(properties)}// 类化构造函数cls,使其具有extend以及implement方法,从而使其能够轻松进行扩展function classify(cls) {cls.extend = Class.extend cls.implement = implementreturn cls}// Mutators define special properties.// Class.Mutators定义了三个特定的属性,从而在调用Class.create的时候如果用户传入了对应的属性则进行对应方法的调用// 注意:三个函数中的this都指向新创建的SubclassClass.Mutators = {'Extends': function(parent) {// 新创建类的原型var existed = this.prototype// 创建以父类原型为原型对象的对象(该对象继承自parent.prototype)var proto = createProto(parent.prototype)// Keep existed properties.将Subclass的静态属性mix给protomix(proto, existed)// Enforce the constructor to be what we expect.// 将proto的构造函数指向Subclassproto.constructor = this// Set the prototype chain to inherit from `parent`.// Subclass的原型指向proto,proto的原型指向parent.prototype,从而形成原型链继承this.prototype = proto// Set a convenience property in case the parent's prototype is needed later.// 方便对父类的原型的方法和属性进行调用this.superclass = parent.prototype},// implements为JS保留关键字,故开头大写'Implements': function(items) {// 保证参数为数组,方便后面调用isArray(items) || (items = [items])var proto = this.prototype, itemwhile (item = items.shift()) {// 直接将被继承对象的原型(不是类的则将其本身)的属性赋值给Subclass原型mix(proto, item.prototype || item)}},// 静态属性'Statics': function(staticProperties) {mix(this, staticProperties)}}// Shared empty constructor function to aid in prototype-chain creation.function Ctor() {}// See: http://jsperf.com/object-create-vs-new-ctorvar createProto = Object.__proto__ ?function(proto) {return { __proto__: proto }} :function(proto) {Ctor.prototype = protoreturn new Ctor()}// Helpers// ------------function mix(r, s, wl) {// Copy "all" properties including inherited ones.for (var p in s) {if (s.hasOwnProperty(p)) {if (wl && indexOf(wl, p) === -1) continue// 在 iPhone 1 代等设备的 Safari 中,prototype 也会被枚举出来,需排除if (p !== 'prototype') {r[p] = s[p]}}}}var toString = Object.prototype.toStringvar isArray = Array.isArray || function(val) {return toString.call(val) === '[object Array]'}var isFunction = function(val) {return toString.call(val) === '[object Function]'}var indexOf = Array.prototype.indexOf ?function(arr, item) {return arr.indexOf(item)} :function(arr, item) {for (var i = 0, len = arr.length; i < len; i++) {if (arr[i] === item) {return i}}return -1}


0 0
原创粉丝点击