关键词

Underscore源码分析

Underscore源码分析完整攻略

简介

Underscore.js是JavaScript工具库中非常受欢迎的一个库,提供了一系列函数,可以简化JavaScript编程过程中的常见任务。其源码具有较高的可读性,并且拥有多种开发风格的版本,特别方便开发者进行源码的学习和理解。

如何获取源码

Underscore.js的最新版本可以通过官方网站或者Github进行下载。其中,在Github上可以查看完整的源码。可以通过以下命令将其下载到本地:

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

也可以通过直接下载zip文件的方式进行源码下载。

源码分析步骤

Step 1:查看目录结构

下载完源码后,我们可以查看Underscore.js的目录结构。该目录结构如下:

.
|-- LICENSE
|-- README.md
|-- underscore.js
|-- underscore-min.js
|-- underscore-min.map
`-- test
    |-- array.js
    |-- chain.js
    |-- collection.js
    |-- function.js
    |-- index.html
    |-- internal.js
    |-- math.js
    |-- object.js
    |-- string.js
    `-- template.js

其中,underscore.js是完整的源码,而underscore-min.jsunderscore-min.map则是压缩后的版本,可以用于生产环境。test文件夹下包含了对Underscore.js各个函数进行测试的文件。

Step 2:格式化源码

Underscore.js中的源码使用的是未压缩的形式,因此代码的缩进、空格等并不规范。为了便于阅读源码,我们首先需要将源码进行格式化。可以使用Beautify Online这样的工具对其进行格式化。

Step 3:了解Underscore.js中的函数

Underscore.js库中的函数非常多,其中部分函数由类似于_.functionName的方式定义,而另一部分函数由原型对象的方式定义。

如下面是Underscore.js中通过变量定义的函数:

// Underscore.js中通过变量定义的函数
_.identity = function(value) {
  return value;
};

与以下通过原型对象方式定义的函数:

// Underscore.js中通过原型对象方式定义的函数
_.sortBy = function(obj, iteratee, context) {
  iteratee = cb(iteratee, context);
  return _.pluck(_.map(obj, function(value, index, list) {
    return {
      value: value,
      index: index,
      criteria: iteratee(value, index, list)
    };
  }).sort(function(left, right) {
    var a = left.criteria;
    var b = right.criteria;
    if (a !== b) {
      if (a > b || a === void 0) return 1;
      if (a < b || b === void 0) return -1;
    }
    return left.index - right.index;
  }), 'value');
};

对于Underscore.js中函数的各个参数以及返回值的意义,也需要进行仔细地分析和研究。

Step 4:调试Underscore.js

如果要深入地了解Underscore.js的工作原理,调试是非常必要的。通常情况下,可以使用浏览器的Live Edit功能进行调试,或者使用Chrome的DevTools的调试器进行调试。调试的过程中,可以通过打断点、单步调试等方式查看代码的执行过程,包括函数调用和参数传递等细节。

示例

示例1:_.once函数的源码分析

下面是Underscore.js中的_.once函数的源码:

_.once = function(func) {
  var ran = false, memo;
  return function() {
    if (ran) return memo;
    ran = true;
    memo = func.apply(this, arguments);
    func = null;
    return memo;
  };
};

该函数接收一个函数作为参数,返回一个新的函数。新函数在第一次调用的时候会执行传入的函数,之后再次调用则不会执行。

代码首先定义了一个ran变量,用于标识该函数是否已执行过。memo变量则表示传入函数的返回值。

新函数会首先判断ran变量,如果为true则直接返回memo变量,否则将ran标识设置为true,并且执行传入的函数,将其返回值存储到memo变量中。之后将传入函数的引用设为null,并且返回memo变量。

这个函数可以用于将一个函数转换为只有在第一次调用时才会执行的函数,这通常在需要将一个函数作为回调函数进行存储时非常有用,例如确保只加载一次资源等。

示例2:_.pluck函数的源码分析

下面是Underscore.js中的_.pluck函数的源码:

_.pluck = function(obj, key) {
  return _.map(obj, _.property(key));
};

该函数接收两个参数,一个对象数组和一个字符串参数。返回一个包含每个对象中指定属性值的新数组。

函数使用了_.map函数,在对象数组中遍历每个元素,对于每个元素使用_.property函数获取指定属性的值,并将其返回到新的数组中去。

这个函数可以用于获取对象数组中所有指定属性名的值。例如:

var people = [{name: 'Alice', age: 25}, {name: 'Bob', age: 30}];
var names = _.pluck(people, 'name');
// expected output: ["Alice", "Bob"]

本文链接:http://task.lmcjl.com/news/3372.html

展开阅读全文