新旧对比

在准备课程的这个时间 https://github.com/madrobby/zepto/blob/master/src/zepto.js#files 其中的代码中,zepto.Z是这样实现的:


  function Z(dom, selector) {
    var i, len = dom ? dom.length : 0
    for (i = 0; i < len; i++) this[i] = dom[i]
    this.length = len
    this.selector = selector || ''
  }

  // `$.zepto.Z` swaps out the prototype of the given `dom` array
  // of nodes with `$.fn` and thus supplying all the Zepto functions
  // to the array. This method can be overridden in plugins.
  zepto.Z = function(dom, selector) {
    return new Z(dom, selector)
  }
  
  $.fn = {
    // ...很多属性...
  }
  
  zepto.Z.prototype = Z.prototype = $.fn

再把之前的拿出来对比一下

  // `$.zepto.Z` swaps out the prototype of the given `dom` array
  // of nodes with `$.fn` and thus supplying all the Zepto functions
  // to the array. Note that `__proto__` is not supported on Internet
  // Explorer. This method can be overriden in plugins.
  zepto.Z = function(dom, selector) {
    dom = dom || []
    dom.__proto__ = $.fn
    dom.selector = selector || ''
    return dom
  }
  
  $.fn = {
    // ...很多属性...
  }


两者的异同

第二种实现方式我们已经讲完了,最终它返回的一个数组,并且强制将__proto__修改为$.fn这个对象。这个修改发生在对象上,修改的隐式原型。

而第一种实现方式,是直接将构造函数的原型修改了,即 Z.prototype = $.fn,经过这样一改,构造函数再new出来的对象的隐式原型__proto__自然就指向了$.fn

另外,第一种方式返回的是一个对象数组,而第二种返回的是一个数组。何谓对象数组?——即可以模拟进行数组操作的对象。

var objArray = {
    0: 'abc',
    1: 'bcd',
    2: 'cde',
    length: 3
};

console.log( objArray[1] )
console.log( objArray.length )

那为何不用数组,而用对象数组?——对象本质上更加灵活、直观,例如

objArray.selector = '';