Jquery中extend该怎么写,有几种写法,分别用在什么场景?

1、$.fn=$.prototype 原型方法什么时候使用?
2、$.extend(src) 和 $.fn.extend(src) 有什么区别?
3、浅复制和深复制的区别是什么?

阅读 3.9k
1 个回答

jQuery插件开发分为两种:1 类级别、2 对象级别

$.fn=$.prototype其实就是对象级别

虽然JavaScript 没有明确的类的概念,但是用类来理解它,更容易理解,jQuery便是一个封装得非常好的类,比如我们用语句$("#btn1").css(……),会生成一个 jQuery类的实例

$.fn = $.prototype = {
   init: function( selector, context ) {}
};

1、类级别 $.extend(src)

类级别你可以理解为拓展jQuery类,最明显的例子是$.ajax(...),相当于静态方法,开发扩展其方法时使用$.extend方法

例子1:

$.extend({
    add:function(a,b){return a+b;} 
    minus:function(a,b){return a-b;}
}); 

调用方式

var i = $.add(3,2);
var j = $.minus(3,2); 

例子2:

原型:jQuery.extend( target, object1, [objectN])

var settings = { validate: false, limit: 5, name: "foo" }; 
var options = { validate: true, name: "bar" }; 
$.extend(settings, options); 

返回结果
settings == { validate: true, limit: 5, name: "bar" }

2 对象级别 $.fn.extend(src)
对象级别则可以理解为基于对象的拓展,如$("#table").set(...); 这里这个set呢,就是基于对象的拓展了。开发扩展其方法时使用$.fn.extend方法,

$.fn.extend({

    check:function(){
        return this.each({
            this.checked=true;
        });
    },
    uncheck:function(){
        return this.each({
            this.checked=false;
        });
    }
}); 

调用方式

$('input[type=checkbox]').check();
$('input[type=checkbox]').uncheck(); 

类似于命名空间的扩展

$.xy = {
    add:function(a,b){
        return a+b;
    } ,
    minus:function(a,b){
        return a-b;
    },
    voidMethod:function(){
        alert("void");
    }
};
调用方式
var i = $.xy.add(3,2);
var m = $.xy.minus(3,2);
$.xy.voidMethod(); 

浅复制与深复制

在C语言中其实就是拷贝地址与数据

1、浅复制

浅复制对象A时,对象B将复制A的所有字段,如果字段是内存地址,B将复制地址,若果字段是基元类型,B将复制其值。

浅复制的缺点是如果你改变了对象B所指向的内存地址,你同时也改变了对象A指向这个地址的字段

function copy(target,cloneObj){
    for(var i in cloneObj){
        target[i]  = cloneObj[i];
    }
    return target;
}
var a = {
    a:{ c:"c" },
    b:"b"
}
var t = {};
copy(t,a);
t.a.c ="e";
console.log(a.a.c);//e

2、深复制

这种方式会完全复制所有数据,优点是B与A不会相互依赖(A,B完全脱离关联), 缺点是复制的速度慢,代价大

一种是实现深度拷贝的方案:

function type(obj){
    return Object.prototype.toString.call(obj).slice(8,-1);
}
function deepCopy(target,cloneObj){
    var copy;
    for(var i in cloneObj){
        copy = cloneObj[i];
        if(target === copy){
            continue;
        }
        if(type(copy) === "Array"){
            target[i] = arguments.callee(target[i] || [],copy);
        }else if(type(copy) === "Object"){
            target[i] = arguments.callee(target[i] || {},copy);
        }else{
            target[i] = copy;
        }
    }
    return target;
}

var a = {
    a:{ c:"c" },
    b:"b"
}
var t = deepCopy({},a);
t.a.c ="e";
console.log(a.a.c);//c

可以看到a没有被修改,但是要更深层次的遍历,肯定很耗费性能的。用for-in把所有可枚举的包括原型链上的一起遍历了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏