【问题标题】:Is there a way to refactor this javascript/jquery? [closed]有没有办法重构这个 javascript/jquery? [关闭]
【发布时间】:2011-06-22 08:05:00
【问题描述】:
switch (options.effect) {

case 'h-blinds-fadein':
    $('.child').each(function(i) {
        $(this).stop().css({
            opacity: 0
        }).delay(100 * i).animate({
            'opacity': 1
        }, {
            duration: options.speed,
            complete: (i !== r * c - 1) ||
            function() {
                $(this).parent().replaceWith(prev);
                options.cp.bind('click', {
                    effect: options.effect
                }, options.ch);
            }
        });
    });

    break;

case 'h-blinds-fadein-reverse':
    $('.child').each(function(i) {
        $(this).stop().css({
            opacity: 0
        }).delay(100 * (r * c - i)).animate({
            'opacity': 1
        }, {
            duration: options.speed,
            complete: (i !== 0) ||
            function() {
                $(this).parent().replaceWith(prev);
                options.cp.bind('click', {
                    effect: options.effect
                }, options.ch);
            }
        });
    });

    break;

    ....more cases
}

我还有很多类似的案例。我能想到的一种方法是编写函数?我不确定我对这门语言还是很陌生

对不起,i 是 each() 函数的索引,它是 $('.child') 的大小,而 r 和 c 只是包含 '.孩子'。 r 和 c 可以是任意数字,例如r=5 c=5

【问题讨论】:

  • @JeffAtwood 至少将其移至 codereview.SE

标签: javascript jquery refactoring case switch-statement


【解决方案1】:

而不是使用开关,将特定于案例的数据存储在哈希中。

然后运行主代码块并从哈希中提取任何特定的效果类型。

function doit(e) {
    var hash = {
        'h-blinds-fadein': {
            delay: function(i) { return i; },
            complete: function(i) { return (i !== r * c - 1); }
        },
        'h-blinds-fadein-reverse': {
            delay: function(i) { return (r * c - i); },
            complete: function(i) { return i !== 0; }
        }
    }

    $('.child').each(function(i) {
        $(this).stop().css({
            opacity: 0
        }).delay(100 * hash[e].delay(i)).animate({
            'opacity': 1
        }, {
            duration: options.speed,
            complete: hash[e].complete(i) ||
            function() {
                $(this).parent().replaceWith(prev);
                options.cp.bind('click', {
                    effect: options.effect
                }, options.ch);
            }
        });
    });
}

doit(options.effect);

【讨论】:

  • 谢谢雷诺斯。我不确定这是否过于本地化,但对我来说,Raynos 展示了真正应该如何进行面向对象编程的方式。
  • @whyzee 我认为不是。它可能属于 codereview.SE 虽然
【解决方案2】:

在不知道 i、r 和 c 是什么的情况下,很难重构。这可以浓缩为一个将这些数字作为变量传递的函数——因为最终代码的所有其他部分都是相同的。

【讨论】:

  • 对不起,i 是 each() 函数的索引,它是 $('.child') 的大小,而 r 和 c 只是包含“.child”的网格。 r 和 c 可以是任意数字,例如r=5 c=5
【解决方案3】:

我认为在每个 case 语句中使用 function 是首先要做的事情。

case 'h-blinds-fadein':
    hBlindsFadeIn(options);    
    break;

...

function hBlindsFadeIn(options){
       $('.child').each(function(i) {
            $(this).stop().css({
                opacity: 0
            }).delay(100 * i).animate({
                'opacity': 1
            }, {
                duration: options.speed,
                complete: (i !== r * c - 1) ||
                function() {
                    $(this).parent().replaceWith(prev);
                    options.cp.bind('click', {
                        effect: options.effect
                    }, options.ch);
                }
            });
        });
}

显然您的功能需要在开关之外。

【讨论】:

  • 其实忘了我的答案,@Raynos 有最好的解决方案。
【解决方案4】:

我所能建议的是将实际效果重构为单独的方法,这将使您的 switch 语句更具可读性,即:

switch (options.effect) {

case 'h-blinds-fadein':
    h-blinds-fadein();
    break;

case 'h-blinds-fadein-reverse':
    h-blinds-fadein-reverse();
    break;

    ....more cases
}

function h-blinds-fadein() {
    $('.child').each(function(i) {
        $(this).stop().css({
            opacity: 0
        }).delay(100 * i).animate({
            'opacity': 1
        }, {
            duration: options.speed,
            complete: (i !== r * c - 1) ||
            function() {
                $(this).parent().replaceWith(prev);
                options.cp.bind('click', {
                    effect: options.effect
                }, options.ch);
            }
        });
    });
}

function h-blinds-fadein-reverse() {
    $('.child').each(function(i) {
        $(this).stop().css({
            opacity: 0
        }).delay(100 * (r * c - i)).animate({
            'opacity': 1
        }, {
            duration: options.speed,
            complete: (i !== 0) ||
            function() {
                $(this).parent().replaceWith(prev);
                options.cp.bind('click', {
                    effect: options.effect
                }, options.ch);
            }
        });
    });
}

或者,您可以尝试使用重构函数的 eval 函数:

eval(options.effect+"();");

---- 编辑----

喜欢 Raynos 重构,这个也可以合并。

【讨论】:

  • -1 用于推荐 eval。只推荐window[options.effect]()
  • @Raynos :向我们解释(为了 OP 的利益)为什么 eval 在这种情况下是邪恶的。
  • 如果函数是全局的,那么window[options.effect]() 会快几个数量级。 Eval 通常只是矫枉过正,应该不惜一切代价避免。最好将函数保存在哈希中,然后调用hash[options.effect]()。它会降低性能,而且调试起来很痛苦。
  • @Raynos :现在 OP 知道原因了;)很好的解释。
  • @Lazarus 除非您仍然认为使用 eval 是有效的,否则您可以删除 eval 推荐并且人们可以撤消反对票。
猜你喜欢
  • 2020-12-17
  • 1970-01-01
  • 2021-07-27
  • 1970-01-01
  • 2018-08-18
  • 1970-01-01
  • 2014-04-22
  • 2023-01-07
  • 2019-03-09
相关资源
最近更新 更多