上一次从入口文件中,咱们清晰的看到了整个工程的组成,接下来就开始逐一攻破。jquery
首先core.js引入的模块,能够罗列一下:git
"./var/arr", "./var/document", "./var/getProto", "./var/slice", "./var/concat", "./var/push", "./var/indexOf", "./var/class2type", "./var/toString", "./var/hasOwn", "./var/fnToString", "./var/ObjectFunctionString", "./var/support", "./var/isWindow", "./core/DOMEval"
这里咱们看到了一个很是好的编程习惯,在JavaScript中,不少变量和方法使用起来都比较冗余,并且很容易不当心就被改动,所以,能够将这些基础变量和方法单独维护成一个文件。github
首先能够看arr文件:编程
define( function() { "use strict"; return []; } );
很是简单的返回一个数组直接量(空数组)。这有什么用呢?你能够再看下slice,concat,indexof,push文件:api
define( [ "./arr" ], function( arr ) { "use strict"; return arr.concat; } );
你会恍然大悟,原来提供这个直接量,是用来返回它的类方法的。有人可能会说,这不是绕道而行么?数组能够直接调用concat方法,由于concat是数组的原型方法,全部数组均可以继承。数组
这里不得不说JavaScript的灵活性带来的一个容易出错的地方,覆盖原型方法。无论你是否注意,但不能保证别人不会写出以下代码:app
let arr = [];
arr.concat = function(){...};
一旦别人不当心写出了上面的代码,你会发现你想要的方法变质了。函数
为了使用原汁原味的原生api,常常出现以下写法:spa
//也可以使用apply方法
Array.prototype.concat.call();
[].concat.call();
这样就可使用原生的方法,而且能够绑定方法执行的上下文(call方法说明)prototype
其余的几个模块大同小异,能够看工程中的注释来了解(工程地址欢迎来看)
接下来把整个jquery对象的生产流程过一下:
//首先声明一个jQuery函数(其实就是一个对象的构造函数)
var jQuery = function (selector, context) {
return new jQuery.fn.init(selector, context); }
//其次定义一个扩展方法
jQuery.extend = jQuery.fn.extend = function () {
...
};
//扩展jquery对象
jQuery.extend({
...
});
//这样一波下来,jquery成了有血有肉的骚年了