理解jquery的$.extend
今日在写js插件过程中需要使用扩展对象的方法,便想到了jQuery.extend这个方法,但又不甚了解,故去查了下官方API文档,自己也进行了相应尝试,现将所得总结如下:
$.extend和$.fn.extend的相关用法
jQuery.fn
jQuery.fn = jQuery.prototype = {
init: function( selector, context ) {//….
//……
};
由上述代码可以看出$.fn是相当于$.prototype的,而jQuery是一个封装很好的类,因此当我们使用$.fn时相当于给jQuery这个类添加成员函数,添加后jQuery类的实例即可以使用这个“成员函数”,例如当我们使用$("#input-demo")时相当于创建了一个jQuery实例,当我们要开发一个插件时,例如做一个特殊的编辑框,当它获取焦点时弹框显示当前输入框的内容,我们可以做如下操作:
$.fn.extend({
alertContentWhenFocus: function() {
$(this).on('focus', function() {
alert($(this).val());
)
}
})
$("#input-demo").alertContentWhenFocus();
$.extend(object)
当想给jQuery类添加静态方法时,我们可以做如下操作:
$.extend({
min: function(x, y) {return x < y ? x : y;},
max: function(x, y) {return x > y ? x : y;}
})
jQuery.extend([deep], target , object1 , objectN );
该方法可用于一个或其它多个对象来扩展其中一个对象,并返回被扩展的对象,当我们提供两个或两个以上的对象给$.extend时,对象所有的属性将会添加到目标对象,因此目标对象的参数将会被修改,若我们想保留原对象,我们可以传递一个空对象作为目标对象。当目标对象为空时,jQuery对象将会被默认为目标对象,这时相当于我们在jQuery的命名空间下添加新的功能,这是常见的插件开发模式。
-
deep: 可选属性,当其值为true时,递归合并(又叫做深拷贝),当缺省时默认为false,是不会进行递归的合并操作的,但不可第一个参数传递false
-
target: 目标对象,将附加对象所包含的额外属性传递给目标对象作为新的参数,如果它是唯一的参数,这也为着目标参数被省略,此时,jQuery对象本身将被默认为目标对象,将扩展jQuery的命名空间,当我们想向jQuery中添加新函数时需要用到
-
object1:一个对象,它包含额外的属性合并到第一个参数 objectN:包含额外的属性合并到第一个参数
实例
var object = $.extend({}, object1, object2);
合并object1和object2对象,并在不修改object1对象的情况,合并后结果将会赋值给object
var settings = {first:'hello', second: 'world'};
var options = {first:'hello', second: 'JavaScript',third: 'nodeJs'};
var results = $.extend({}, settings, options);
输出:results 为 {first: "hello", second: "JavaScript", third: "nodeJs"}
$.extend(obj1,obj2)
合并两个对象,并修改第一个对象
var obj1 = {first: 1, second: {height: 178, weight: 70,length:100}};
var obj2 = {second: {height:180, weight:65, width: 90}, third: 90};
$.extend(obj1, obj2);
输出结果为:{first: 1, second: {height:180,weight:65, width: 90}, third: 90}
细心的读者可能会发现,输出的结果和我们预想的结果好像有点不同,输出结果的second属性与目标对象的second属性相比少了length这个属性,原因是在这种情况下,$.extend()的合并操作不是递归的,这意味着当如果目标对象的属性本身是一个对象或者数组,那么第二个对象相同的key属性的value值将会覆盖第一个对象的value值,说明两个对象相同key的value值不是合并的关系,而是覆盖与被覆盖的关系。