Zepto源碼之代碼結構

源碼GITHUB地址:
[email protected]:madrobby/zepto.git

首先我們查看一下代碼結構
image

其中 zepto.js 是其中主文件,本篇文章主要講述的內容就是它:

代碼結構

我們首先使用一下代碼摺疊,查看一下主要結構

image

var Zepto = (function(){
    // code
})()

由此我們可以看出 zepto 使用的是自執行函數。從自執行函數賦值給Zepto上來看,我們可以推斷出,它是一個閉包(當然,它真是一個閉包)。

然後把 Zepto 綁定到全局的windows上面。
接下來再判斷全局(jQuery) 的內容,如果不存在就表示可以使用Zeptowindow.

PS:說多一句,jQuery的構造函數也是使用這種閉包自執行函數的封裝方式,雖然沒有驗證 $ 的賦值問題,但是它有另一種操作。如直接傳入window對象,可以把window對象當作局部對象來使用,當jQuery需要訪問window對象的時候,不用把作用域回退到最頂層,可以更快的訪問window對象。同時,傳入了undefined,也可以縮短查找undefined的作用域鏈。也算是一個騷操作。

// jQuery的騷操作
(function(window,undefined){
    window.jQuery = window.$ = jQuery
    // code
})(window)

核心代碼

我們先把具體實現的細節移除,看一下核心代碼結構

image

var Zepto = (function() {
  var $,zepto = {},

  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 = function(dom, selector) {
    return new Z(dom, selector)
  }

  zepto.isZ = function(object) {
    return object instanceof zepto.Z
  }

  zepto.init = function(selector, context) {
    var dom
    if (!selector) return zepto.Z()
    else if (typeof selector == 'string') {
      // code
    }
    else if (isFunction(selector)) return $(document).ready(selector)
    else if (zepto.isZ(selector)) return selector
    else {
     // code
    }
    return zepto.Z(dom, selector)
  }

  $ = function(selector, context){
    return zepto.init(selector, context)
  }

  $.fn = {
    constructor: zepto.Z,
    // 一些常用方法,如 get ,ready, remove ,add ,filter ,has ,attr ,html 等
    // 我們可以發現,常用的API操作具體實現就在這裏,不過在這裏我們省去了
  }

  zepto.Z.prototype = Z.prototype = $.fn
  $.zepto = zepto

  return $
})()

在這裏我們可以看到, .fn上面掛載了許多屬性與方法。
使用 zepto 的時候,會像 jQuery 一樣的用 $ 來獲取 dom 元素,並剛它轉化成 zepto 元素,從而可以使用 zepto 的方法。

$ = function(selector, context){
  return zepto.init(selector, context)
}

$ 其實是調用 zepto.init() 方法

zepto.init = function(selector, context) {
    var dom
    if (!selector) return zepto.Z()
    else if (typeof selector == 'string') {
      // code
    }
    else if (isFunction(selector)) return $(document).ready(selector)
    else if (zepto.isZ(selector)) return selector
    else {
      // code
    }
    return zepto.Z(dom, selector)
  }

init 方法其實主要就是通過 selector 定義的選擇器來獲取 dom 集合。然後交由 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 = function(dom, selector) {
  return new Z(dom, selector)
}

zepto.Z 方法返回的是函數 Z 的一個實例。函數 Z 會將 dom 展開,變成實例的屬性,並且設置實例的 length 屬性。

騷操作

zepto.Z.prototype = Z.prototype = $.fn

將 Z 的 prototype 指向 .fnZ .fn 的方法。同時配合 isZ 方法來確定對象是一個 zepto 對象。

發佈了88 篇原創文章 · 獲贊 41 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章