多态参数javascript

时间:2012-11-23 13:58:00

标签: javascript jquery parameters polymorphism

我正在尝试模仿jQuery animate()方法去除不受支持的浏览器的opacity样式(当然是Internet Explorer)!

但是,我正在努力模仿jQuery animate()方法接受的参数。

根据jQuery文档:

.animate( properties [, duration] [, easing] [, complete] )
.animate( properties, options )

我想知道的是,该函数如何知道参数2是持续时间还是选项......?

请注意这里的三个参数:

$('#test').animate({opacity:0},200,function(){
    $(this).hide(); 
});

但是我也可以像这样执行相同的功能(注意缓动参数):

$('#test').animate({opacity:0},200,'swing',function(){
    $(this).hide(); 
});

该函数如何知道第三个参数是字符串,而不是函数?

肯定不会这样做????

if(typeof parameter1=='string'){
    // and so on
}

2 个答案:

答案 0 :(得分:2)

  

当然这不是这样做的????

if(typeof parameter1=='string'){
    // and so on
}

是的,这正是它的完成方式。


来自jQuery源代码:

var opt = speed && typeof speed === "object" ? jQuery.extend({},
speed) : {
    complete: fn || !fn && easing || jQuery.isFunction(speed) && speed,
    duration: speed,
    easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
};

opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;

可以通过这种方式重写为更具可读性:

var opt = { };

if (typeof speed == 'object')
    opt = jQuery.extend({ }, speed);
else {

    if (fn)
        opt.complete = fn;
    else if (easing)
        opt.complete = easing;
    else if (jQuery.isFunction(speed))
        opt.complete = speed;

    opt.duration = speed;

    if (fn && easing)
        opt.easing = easing;
    else if (easing && !jQuery.isFunction(easing))
        opt.easing = easing;

}

if (jQuery.fx.off)
    opt.duration = 0;
else if (typeof opt.duration === 'number')
    opt.duration = opt.duration;
else if (opt.duration in jQuery.fx.speeds)
    opt.duration = jQuery.fx.speeds[opt.duration];
else
    opt.duration = jQuery.fx.speeds._default;

更新

如果您想要一种更简单的方法来处理这个逻辑,candy提供了一个名为persuade的简洁数组助手。此函数允许您使用类型列表传入数组(或arguments)对象。您将返回一个数组,其中包含由类型组织的参数。这是处理多态参数的简单方法:

function foo(/* duration, easing, complete */) {
    var args = candy.Arrays.persuade(arguments, [ 'number', 'string', 'function' ]);
    var duration = args[0], easing = args[1], complete = args[2];
    console.log(duration, easing, complete);
}

foo('test');
// => undefined, 'test', undefined

foo(2, function() { });
// => 2, undefined, function() { }

答案 1 :(得分:1)

  

我想知道的是,该函数如何知道参数2是持续时间还是选项......?

如果第二个参数是一个对象,那么它就是选项。如果可以将其解析为int则为duration。如果它是一个函数,那就是callback,否则就是easing