Class.js 分析

实现了继承和父类中调用子类方法
// The base Class implementation.
  function Class(o) {
    // Convert existed function to Class.
    if (!(this instanceof Class) && isFunction(o)) {
      return classify(o)
    }
  }


 
  //核心方法,SubClass用于实现动态继承,每次返回的SubClass都不是同一个函数
  //每个返回的SubClass函数的prototype值是一个SubClass的对象(并没有调用其构造函数,通过createProto方法实现)
  Class.create = function(parent, properties) {
    if (!isFunction(parent)) {
      properties = parent
      parent = null
    }


    properties || (properties = {})
    parent || (parent = properties.Extends || Class)//properties.Extends就是上当前的SubClass函数
    properties.Extends = parent//第一次时Extends为Class,properties没有Extends,Extends很重要,用于构建prototype chain


    // 当new 时,执行下面SubClass构造函数
    function SubClass() {
      //parent 是上一个SubClass函数,不管多少层SubClass,this永远指new出的对象
      parent.apply(this, arguments)


      // 调用自定义的初始化函数,this.constructor === SubClass,由于每个SubClass都不一样,只有当前new的SubClass对象为true
      // this.initialize 在prototype chain上找到就会被调用
      if (this.constructor === SubClass && this.initialize) {
        this.initialize.apply(this, arguments)//这里的this.initialize未必是当前对象的,可能是prototype chain上某一个对象的
      }
    }


    // Inherit class (static) properties from parent.
    //复制函数的属性或方法(static properties)
    if (parent !== Class) {
      mix(SubClass, parent, parent.StaticsWhiteList)
    }


    // 实现了prototype chain
    implement.call(SubClass, properties)


    // Make subclass extendable.
    return classify(SubClass)
  }




  function implement(properties) {
    var key, value


    for (key in properties) {//Extends属性会最后被遍历
      value = properties[key]


      if (Class.Mutators.hasOwnProperty(key)) {// 实现了prototype chain
        Class.Mutators[key].call(this, value)
      } else {
        this.prototype[key] = value//把传入值赋给新的SubClass的prototype
      }
    }
  }




  //这里的this实际上指的是当前的SubClass函数,实际上的调用是:SubClass.extend,所以this指的是SubClass
  Class.extend = function(properties) {
    properties || (properties = {})
    properties.Extends = this


    return Class.create(properties)
  }



  //给返回的SubClass函数增加extend方法
  function classify(cls) {
    cls.extend = Class.extend
    cls.implement = implement
    return cls
  }




  // Mutators define special properties.
  Class.Mutators = {

    //实现了prototype chain,this指新的SubClass函数
    'Extends': function(parent) {
      var existed = this.prototype
      var proto = createProto(parent.prototype)//创建了一个新的SubClass对象,没有调用其构造函数,用于存储传入的属性,新对象连接了上一个SubClass函数


      // 把传入的属性赋给新对象
      mix(proto, existed)


      // Enforce the constructor to be what we expect.
      proto.constructor = this


      // Set the prototype chain to inherit from `parent`.
      //改变新的SubClass函数prototype为新对象
      this.prototype = proto


      // Set a convenience property in case the parent's prototype is
      // needed later.
      this.superclass = parent.prototype


      // Add module meta information in sea.js environment.
    },


    'Implements': function(items) {
      isArray(items) || (items = [items])
      var proto = this.prototype, item


      while (item = items.shift()) {
        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-ctor
  var createProto = Object.__proto__ ?
      function(proto) {
        return { __proto__: proto }
      } :
      function(proto) {
        Ctor.prototype = proto
        return 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.toString
  var isArray = Array.isArray


  if (!isArray) {
    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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值