JavaScript switch语句是线性还是恒定时间?

时间:2016-12-12 20:42:38

标签: javascript switch-statement time-complexity constant-time

我的网站上有以下JavaScript,因此当执行某些特定搜索时,答案会被硬编码到特定页面:

function redirect() {
    var input = document.getElementById('searchBox').value.toLowerCase();

    switch (input) {
      case 'rectangular':
        window.location.replace('http://www.Example.com/Rectangular/');
        break;
      case 'elephant':
        window.location.replace('http://www.Example.com/Elephants/');
        break;
      case 'coils':
        window.location.replace('http://www.Example.com/Parts/');
        break;
      default: // No keyword detected: submit the normal search form.
        return true;
        break;
    }
    return false; // Don't let the form submit
}

我想知道JavaScript中的搜索语句是否与case语句的数量或常数时间呈线性关系?如果是线性的,有没有更好的方法来编写这段代码,所以无论我编码的特殊情况如何,它都是恒定的时间?

2 个答案:

答案 0 :(得分:1)

规范没有为switch语句提供任何时间复杂性保证。这样做的语义需要对case表达式进行顺序求值,因此在一般情况下它的行为是线性的。

如果所有情况都是常量字符串或数字(并且相当简单),引擎可以自由地优化评估,因此您可以期望时间复杂度不变。

如果要强制执行优于线性的行为,则需要使用Map作为查找表:

var redirects = new Map([
    ['rectangular', 'http://www.Example.com/Rectangular/'],
    ['elephant', 'http://www.Example.com/Elephants/'],
    ['coils', 'http://www.Example.com/Parts/']
]);
function redirect() {
    var input = document.getElementById('searchBox').value.toLowerCase();
    if (redirects.has(input)) {
        window.location.replace(redirects.get(input));
        return false; // Don't let the form submit
    } else {
        return true;
    }
}

在ES6之前的环境中,您也可以将对象用于相同的目的。所有引擎都已实现O(1)属性查找,尽管它们并未正式要求。

答案 1 :(得分:1)

这里相当于Bergi在ES5中的答案。与您现在使用的相比,它会更快,也更容易修改。

var _redirectlist = {
  'rectangular': 'http://www.Example.com/Rectangular/',
  'elephant': 'http://www.Example.com/Elephants/',
  'coils': 'http://www.Example.com/Parts/'
};

function redirect() {
  var input = document.getElementById('searchBox').value.toLowerCase();

  // Redirect if we have the input in our list
  if (_redirectlist.hasOwnProperty(input)) {
    window.location.replace(_redirectlist[input]);
    return false;
  }

  return true;
}