jquery1.4 jquery1.4下载
这里使用了 jQuery1.4,为什么使用 1.4 因为 1.4 很多特性没有添加分析起来相对容易。
extend 可以说是 jQuery 用的最多的函数之一了,除了核心的几个函数之外其他的几乎全部用 extend 进行原型或者静态函数的扩展。下面来看看 extend 如果完成这样的工作的吧
jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;
// Handle a deep copy situation
// 深度拷贝
if ( typeof target === "boolean" ) {
deep = target; // 修正深度拷贝
target = arguments[1] || {}; // 修正目标
// skip the boolean and the target // 如果是深度拷贝 修正循环(跳过第一个参数(0)和目标(1))
i = 2;
}
// Handle case when target is a string or something (possible in deep copy)
// 确保目标元素是对象且不是函数,但可以是函数对象(new 函数)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// extend jQuery itself if only one argument is passed
// 当扩展的对象只有一个的时候,就视为扩展 jQuery
if ( length === i ) {
target = this; // 修正 this 为jQuery
--i;
}
// 遍历参数
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
// 遍历不是 null 的值(对象)
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
// 遍历这个对象下面的属性
for ( name in options ) {
src = target[ name ]; // 目标的属性
copy = options[ name ]; // 要拷贝的属性
// Prevent never-ending loop
// 防止无限循环
if ( target === copy ) {
continue;
}
// Recurse if we're merging object literal values or arrays
// 深拷贝,且 copy 是对象或者数组
/**
* deep => true
* copy == true
* copy => 必须是绝对对象 或 copy 是一个数组
*
*/
if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {
/**
* 如果目标元素和要拷贝的元素有相同的 key 并且也是对象或者数组那么就返回目标对象的 key
* 否则创建一个对应的类型用于保存数据
*/
var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src
: jQuery.isArray(copy) ? [] : {};
// Never move original objects, clone them
// 对子项进行拷贝
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
// 不是深拷贝
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
};
下面我列出一下 extend 的一些用法 手册描述
1、这种是最基本的用法
var t = $.extend({a:"123"}, {b:'456'});
console.log(t);
//Object {a: "123", b: "456"}
2、深度拷贝
var o1 = {
txt: "123",
a: {
'a_text': 'a_text'
}
};
var o2 = {
txt1: '456',
b: {
'b_text': '123'
}
};
debugger;
var t = $.extend(false,o1,o2);
t['b']['b_text'] = '改变成文本';
console.log(t);
console.log(o1,o2);
// -----------------------------深度克隆------------------------------------
var o1 = {
txt: "123",
a: {
'a_text': 'a_text'
}
};
var o2 = {
txt1: '456',
b: {
'b_text': '123'
}
};
debugger;
var t = $.extend(true,o1,o2);
t['b']['b_text'] = '改变成文本';
console.log(t);
console.log(o1,o2);
我们看当深度克隆参数为 false 的时候,扩展出来的对象 key 为 b 的和元素对象 key 为 b 的是指向的同一个引用。所以当我改变了克隆回来的对象 t 值 'b_text' 的时候原始对象也跟着变了。
再来看看深度克隆的情况,当我改变了克隆回来的对象 t 值 'b_text' 的时候原始对象没有跟着变了。
3、接下来看看为 jQuery 扩展插件的情况
jQuery.extend = jQuery.fn.extend = function(){};
他这里为 jQuery 静态函数 和 原型都添加了 extend 函数, 所以我们要编写插件只需要给原型添加一个扩展函数就可以啦。
$.fn.extend({tudou:function(){alert('hello tudou')}});
看一下他这里怎么实现的,其实原理很简单。
// 当扩展的对象只有一个的时候,就视为扩展 jQuery
if ( length === i ) {
target = this; // 修正 this 为jQuery
--i;
}
当你只传递一个对象的时候他会把 扩展的目标指向当前 this,所以能很方便的进行插件编写。
好啦结束了。。。