JQuery模块 一: 构造函数,实例对象 ,以及核心扩展函数
实例对象
1 使用方法:$() 即可构造除JQuery对象
//核心入口
jQuery = function(selector, context) {
return new jQuery.fn.init(selector, context);
},
// fn 属性 保存JQuery 函数的原型,为了方便调用;减少单词长度
jQuery.fn = jQuery.prototype = {....};
// init 核心函数位于原型上
jQuery.fn.init = function(){....}
可以看出 当我们调用 $() 后,内部 new jQuery.fn.init();此时this指向发生变化。得到的对象原型改为 init函数的原型。肯定有问题,源码中还有下面这一句:
// 将init 函数得原型改为 JQuery 的原型
jQuery.fn.init.prototype = jQuery.fn;
这样返回得对象就拥有了,Query的所有方法和属性
jQuery.extend
// 用法 $.extend(true,obj,obj...) 合并对象到第一个个对象,
jQuery.extend = jQuery.fn.extend = function() {
var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
//判断arguments[0]是不是 Boolean 值,如果是,且为true的话,将进行深拷贝。
if (typeof target === "boolean") {
deep = target;
target = arguments[i] || {};
i++;
}
if (typeof target !== "object" && !jQuery.isFunction(target)) {
target = {};
}
// i === length 如果只有一个参数 例如 $(obj) || $(true,obj)
// 则在this上扩展即JQ
if (i === length) {
target = this;
i--;
}
for (; i < length; i++) {
if ((options = arguments[i]) != null) {
// 遍历所有属性
for (name in options) {
// 取出要合并的属性
src = target[name];
copy = options[name];
// 避免循环引用 例如: var a = {huge:88}; target = a; origin = {cc:a} 此时跳出循环
if (target === copy) {
continue;
}
// 如果ideep = true 且 copy 属性值为对象或者数组,则递归
if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
//如果 copyIsArray = true 则为数组 否则为对象
if (copyIsArray) {
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src: [];
} else {
// 如果没有相同属性就为 {} 否则 覆盖原来的属性
clone = src && jQuery.isPlainObject(src) ? src: {};
}
// 递归
target[name] = jQuery.extend(deep, clone, copy);
} else if (copy !== undefined) {
target[name] = copy;
}
}
}
}
return target;
};