Underscore源碼解析

Underscore源碼解析


前言

Underscore是一個JavaScript工具庫,它提供了許多操作集合、數組、函數等的實用函數。簡單說它集成了好多工具函數,不用自己寫一些常用的函數了。

準備

軟件 描述
git 代碼管理工具

步驟

克隆代碼到本地:

 git clone https://github.com/jashkenas/underscore.git

查看目錄結構:
這裏寫圖片描述

從目錄結構中可以看到,只有一個docs(文檔)和test(測試)目錄,然後看下根目錄下,可以推測源碼文件就一個underscore.js文件(min文件是壓縮文件)

查看package.json文件(TODO:package.json文件解析):
這裏寫圖片描述

簡單看下項目的依賴(devDependencies)和 scripts,大致瞭解下項目構建,怎麼打包。可以知道構建是通過如下腳本(主要是minify插件對源碼壓縮)執行的:

npm run minify -- --source-map --source-map-url \" \" -o underscore-min.js

查看源碼:
1、首先收攏代碼(不要被代碼量嚇到),可以看到所有的代碼都放到一個閉包裏面,裏面是一個立即執行的函數。
這裏寫圖片描述

2、展開閉包函數,可以看到首先是全局變量的聲明。
這裏寫圖片描述

// Baseline setup
  // --------------

  // Establish the root object, `window` (`self`) in the browser, `global`
  // on the server, or `this` in some virtual machines. We use `self`
  // instead of `window` for `WebWorker` support.
  var root = typeof self == 'object' && self.self === self && self ||
            typeof global == 'object' && global.global === global && global ||
            this ||
            {};// 獲取全部變量

  // Save the previous value of the `_` variable.
  var previousUnderscore = root._;

  // Save bytes in the minified (but not gzipped) version:
  var ArrayProto = Array.prototype, ObjProto = Object.prototype; // 保存js引擎的數組和對象的原型
  var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;

  // Create quick reference variables for speed access to core prototypes.
  var push = ArrayProto.push,
      slice = ArrayProto.slice,
      toString = ObjProto.toString,
      hasOwnProperty = ObjProto.hasOwnProperty;// 保存js引擎的原型方法

  // All **ECMAScript 5** native function implementations that we hope to use
  // are declared here.
  var nativeIsArray = Array.isArray,
      nativeKeys = Object.keys,
      nativeCreate = Object.create;

  // Naked function reference for surrogate-prototype-swapping.
  var Ctor = function(){};

  // Create a safe reference to the Underscore object for use below.
  var _ = function(obj) {
    if (obj instanceof _) return obj;
    if (!(this instanceof _)) return new _(obj);// 確保全局對象 _ 被安全創建
    this._wrapped = obj;
  };

  // Export the Underscore object for **Node.js**, with
  // backwards-compatibility for their old module API. If we're in
  // the browser, add `_` as a global object.
  // (`nodeType` is checked to ensure that `module`
  // and `exports` are not HTML elements.)
  if (typeof exports != 'undefined' && !exports.nodeType) {
    if (typeof module != 'undefined' && !module.nodeType && module.exports) {
      exports = module.exports = _;
    }
    exports._ = _;
  } else {
    root._ = _;
  }// 暴露全局對象 _ (所有的方法和屬性都在_裏面)

  // Current version.
  _.VERSION = '1.9.1'; // 版本信息

3、在全局對象上添加方法
這裏寫圖片描述

可以看到在全局對象_上添加了許多方法map、reduce、……….,這些方法的Api介紹官網都有,這裏就不多說了。

4、函數調試解析,一般方法通過名稱就可以知道它的作用,但是想了解內部實現的話可以通過調試。(TODO)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章