jQuery工具中提供了extend(...)方法,实现一个或者多个其它对象扩展一个对象并且返回扩展后的对象。
下面的示例来演示jQuery.extend()是如何扩展对象的。
1.准备3个对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
var
target = {
container:
'container'
};
var
src1 = {
chart: {
type:
'column'
},
xAxis: {
categories: [
'1月'
,
'2月'
,
'3月'
,
'4月'
,
'5月'
],
name:
"xAxis"
},
yAxis: {
min: 0
},
data: {
key: {
}
}
};
var
src2 = {
chart: {
type:
'area'
},
title: {
text:
'未命中率'
},
xAxis: {
categories: [
'1月'
,
'2月'
,
'3月'
,
'4月'
,
'5月'
,
'6月'
],
enable:
true
},
yAxis: {
min: 0,
max: 10
}
};
|
说明:
target:要扩展的目标对象,src1 src2:用来扩展目标对象的对象。
2. jQuery.extend(target, src1, src2)
1
2
3
4
|
var
rs1 = jQuery.extend(target, src1, src2);
console.info(target);
console.info(rs1);
console.info(target === rs1);
|
运行的结果是:target === rs1 为true, 说明对target扩展成功,这个时候target发生改变,且结果为:
如上图target对象的值,和1中准备的3个对象(target,src1,src2)仔细对比会发现一个问题,aAxis对象的中没有了name属性。这个问题的产生要归到extends()方法的第一个可选参数deep,默认为false,意思是不进行递归扩展。
如果将上述扩展改为:
1
|
jQuery.extends(
true
, target, src1, src2)
|
测试结果如下:
如上图红色框可以看出对target进行了递归合并。
3.只想获取一个合并后的对象,并不想改变原始目标
1
|
var
rs1 = jQuery.extend(
true
, {}, target, src1, src2);
|
这样进行扩展,将{}对象作为目标对象,target对象作为扩展目标对象的对象。这样target对象不会发生变化,同时返回的结果rs1和2中deep设置为true的结果是相等的。
4. 小心3中用{}作为目标对象合并
2中的结果表明target对象确实被src1,src2进行了扩展,注意一个问题在对target对象进行扩展的时候,如果src(源)存在目标对象的属性则进行覆盖,不存在则保持target对象属性值不变。deep的取值是针对src(扩展目标对象的对象)是否进行递归合并而言的,因此可以根据实际情况比较清楚的选择deep的取值。
3中的测试将deep不设置或设置为false,则rs1的结果将和2中第一个测试结果是相等的。
下面来说明一下3中的小心之处:如果target对象是一个嵌套对象,src1,src2保持不变。
1
2
3
4
5
6
|
var
target = {
container:
'container'
,
xAxis: {
version:
'1.0'
}
};
|
我们可以看到target对象现在是一个嵌套对象,且xAxis对象中的属性在src1,src2中都不存在。
进行jQuery.extend({},target, src1,src2), jQuery.extend(false,{}, target, src1,src2)操作之后发现返回的结果是:
这个问题产生不是方法的问题,只是在实际应用中很可能碰到,主要因为人为设置{}为目标对象的时候,忽略的本质上的目标对象target,因此在使用3中的方式来避免修改目标对象的同时应该显式的将deep设置true。
使用jQuery.extend(true, {}, target, src1, src2)结果如下:
这样扩展的结果才能够保证目标对象的完整。不过,如果实际中并不需要对src1, src2进行递归合并的话,这个时候可以将target对象复制一份在进行操作。
5. 无(隐式的,目标对象肯定是有的)target扩展$.extend(src), $.fn.extend(src)
1
|
$.extend(src1)
|
将src1扩展到$(jQuery)全局对象中。通过Firebug查看如下图:
1
|
$.fn.extend(src1);
|
将src1扩展到$(jQuery)实例对象中。通过Firebug查看如下图:
通过上面两个示例清楚的看到src1分别扩展到了jQuery全局对象和实例对象中去,值得注意的是这正是jQuery插件常用方法。
最后一个小扩展,对命名空间进行扩展。
1
2
3
|
$.namespace = {
}
|
为了避免JavaScript的全局变量命名污染,经常会用到一个变量名作为一个库或者一个组件的命名空间,如jQuery就是jquery库的全局变量名也可以说是命名空间。
我们可以通过jQuery.extend()对命名空间进行扩展,注意事项和用法同文中2,3介绍相同,这里命名空间作为了target对象。
1
|
$.extend($.namespace, src1);
|
这里namespace作为jQuery全局对象的一个属性,属性的值是一个对象,在这个对象里可以可以对代码进行组织,封装。namespace可以看作是被封装和组织的这些代码的命名空间。
如下图所示,可以看出src1对象扩展到$.namsespace对象中:
写到这里,可以看到JavaScript一切是对象的强大之处,可以将对命名空间的扩展方法定义为:
1
|
jQuery.extend([deep], namespace, src1, src2, ... , srcN)
|
PS:今天用到jQuery.extend()方法的时候,手头有个文档加上网上的一些文章看了看,不过还是费了一点神,虽说解释起来并没有太多难点,实际开发中却能发现好多东西。一句jQuery.extend()方法用来对目标对象进行扩展的方法的说明,简单,却并不易懂,毕竟JavaScript的对象实在强大。
本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1414366,如需转载请自行联系原作者