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
- Arale Class基类源码解析
- Arale aspect切面编程源码解析
- Arale Base源码分析(含Attribute)
- 支付宝前端框架之Arale-class研究
- Android 消息系统解析(Handler.class及相关类源码解析)
- Class类源码浅析
- arale插件-uploadjs解读arale组件
- jdk源码解析(六)——类(class)文件结构
- thinkphp源码解析 (Version 3.1) -2 /Lib/Core/Think.class
- thinkphp源码解析 (Version 3.1) -3 /Lib/Core/App.class
- thinkphp源码解析 (Version 3.1) -4 /Lib/Core/Dispatcher.class
- Java源码解析(2) —— Class(1)
- Java源码解析(3) —— Class(2)
- Java源码解析(4) —— Class(3)
- Java源码解析(5) —— Class(4)
- ThreadLocal类源码解析
- Object类源码解析
- Vector类源码解析
- 稀疏表示介绍(下)
- 第一次算分作业 分治法
- 黑马程序员——数组
- Grid Infrastructure Single Client Access Name (SCAN) Explained (文档 ID 887522.1)
- 关于VMware11装Mac10.10遇到的问题总结
- Arale Class基类源码解析
- 斐波那契查找算法解析
- 第一只python小爬虫
- Hdu 5187 zhx's contest(数学)
- 【TCP/IP】TCP协议
- 南邮NOJ没有被接待的童鞋
- 微信支付功能集成
- CUDA 6.0 统一寻址
- Python、Java、Scala、Go Package对照表