js学习的点小积累

本文详细解析了jQuery.extend()方法的工作原理,并通过实例展示了如何使用该方法进行浅拷贝和深拷贝,适用于需要扩展jQuery对象或进行属性合并的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对Jquery也有了个初步的了解
对其源码的学习是源于$.extend方法的运用上

先看Jquery.extend的方法

jQuery.extend = jQuery.fn.extend = function() {
// copy reference to target object
var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;

// Handle a deep copy situation
if ( target.constructor == Boolean ) {
deep = target;
target = arguments[1] || {};
}

// extend jQuery itself if only one argument is passed
if ( al == 1 ) {
target = this;
a = 0;
}

var prop;

for ( ; a < al; a++ )
// Only deal with non-null/undefined values
if ( (prop = arguments[a]) != null )
// Extend the base object
for ( var i in prop ) {
// Prevent never-ending loop
if ( target == prop[i] )
continue;

// Recurse if we're merging object values
if ( deep && typeof prop[i] == 'object' && target[i] )
jQuery.extend( target[i], prop[i] );

// Don't bring in undefined values
else if ( prop[i] != undefined )
target[i] = prop[i];
}

// Return the modified object
return target;
};



下面说说怎么样运用该方法

1.方式一, 最基本的方式

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>$.extend() Example</title>
<link rel="stylesheet" type="text/css" href="../common.css">
<script type="text/javascript"
src="../scripts/jquery-1.2.1.js"></script>
<script type="text/javascript"
src="../scripts/support.labs.js"></script>
<script type="text/javascript">
var target = { a: 1, b: 2, c: 3 };
var source1 = { c: 4, d: 5, e: 6 };

$(function(){
$('#targetBeforeDisplay').html($.toSource(target));
$('#source1Display').html($.toSource(source1));
$('#source2Display').html($.toSource(source2));
$.extend(target,source1);

$('#targetAfterDisplay').html($.toSource(target));
});
</script>
<style>
label { float: left; width: 108px; text-align: right; }
p { clear: both; }
label + span { margin-left: 6px; }
fieldset { width: 360px }
</style>
</head>

<body>
<h1>$.extend() Example</h1>
<fieldset>
<legend>$.extend() Example</legend>
<p>
<label>target (before) =</label>
<span id="targetBeforeDisplay"></span>
</p>
<p>
<label>source1 =</label>
<span id="source1Display"></span>
</p>
<p>
<label>source2 =</label>
<span id="source2Display"></span>
</p>
<p>
<label>target (after) =</label>
<span id="targetAfterDisplay"></span>
</p>
</fieldset>
</body>
</html>

输出

[quote]
target (before) = {a:1,b:2,c:3}

source1 = {c:4,d:5,e:6}

source2 = {e:7,f:8,g:9}

target (after) = {a:1,b:2,c:4,d:5,e:6}
[/quote]

第二种方式
只改了核心执行部分

<script type="text/javascript">
var target = { a: 1, b: 2, c: 3, location: { city: 'Boston'} };
var source1 = { c: 4, location: { state: 'MA'}, d: 5, e: 6 };
var source2 = { e: 7, f: 8, g: 9 };

$(function(){
$('#targetBeforeDisplay').html($.toSource(target));
$('#source1Display').html($.toSource(source1));
$('#source2Display').html($.toSource(source2));
//$.extend(target,source1);
$.extend(true, target, source1);
$('#targetAfterDisplay').html($.toSource(target));
});
</script>


输出
[quote]
target (before) = {a:1,b:2,c:3,location:{city:'Boston'}}

source1 = {c:4,location:{state:'MA'},d:5,e:6}

source2 = {e:7,f:8,g:9}

target (after) = {a:1,b:2,c:4,location:{city:'Boston',state:'MA'},d:5,e:6}

[/quote]

我们开始分析源代码
首先
[quote]

// copy reference to target object
var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false;

[/quote]
设置target的值,如果一个参数有值,就为第一个参数值,否则设置一个空的对象
设置变量a,a1值,deep定义为false默认不是深度copy

[quote]

// Handle a deep copy situation
if ( target.constructor == Boolean ) {
deep = target;
target = arguments[1] || {};
}

[/quote]
处理深度copy情形,如果第一个参数值的构造子为Boolean对象,即设置deep值和改变target值为第二个参数

[quote]

// extend jQuery itself if only one argument is passed
if ( al == 1 ) {
target = this;
a = 0;
}

[/quote]
如果仅为一个参数的情形,target设置为自己,设置a=0;

[quote]

var prop;

for ( ; a < al; a++ )
// Only deal with non-null/undefined values
if ( (prop = arguments[a]) != null )
// Extend the base object
for ( var i in prop ) {
// Prevent never-ending loop
if ( target == prop[i] )
continue;

// Recurse if we're merging object values
if ( deep && typeof prop[i] == 'object' && target[i] )
jQuery.extend( target[i], prop[i] );

// Don't bring in undefined values
else if ( prop[i] != undefined )
target[i] = prop[i];
}


[/quote]

如果参数只有一个,那么从第一个参数开始,否则默认从第二个参数开始
先将参数的值付给prop对象
在迭代每个临时prop
对应参试为{a:1,b:3}形式的 for in 操作
i取值为key-value的key值

如果target的值(原始值)和参试中迭代的值有相等的时,继续执行循环跳出本次循环


// Recurse if we're merging object values
if ( deep && typeof prop[i] == 'object' && target[i] )
jQuery.extend( target[i], prop[i] );

如果为深度copy 并且第I个对象的值为“object”类型 并且 target对象的第I个值为真
那么就继续深度COPY,让其prop[i]的值继续copy到target[i]中(这里只支持两层)


else if ( prop[i] != undefined )
target[i] = prop[i];

继续看就是,非深度COPY的情形。赋值到即可

//-----------------------------------------------------------------
以上就是我的理解,其实看懂一段源码还真需要些时间, 虽然看懂之后觉得这是很简单的
但是认真读下来还是有收获的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值