这种合并应该"失败",对吗?

200*_*ess 9 javascript mergesort if-statement keyword

在Code Review上查看这个mergesort实现时发现了一些奇怪的东西......

/************************************************************
 * Mergesort implementation
 ***********************************************************/

function sort(array) {
  var len = array.length;
  var middle = Math.floor(len*0.5);
  var left = array.slice(0,middle);
  var right = array.slice(middle, len);

  if (len == 1) {
    return array;
  } else {

  }

  return merge(sort(left), sort(right));
}


function merge(left, right) {
  var a = left.length;
  var b = right.length;


  if (a > 0 && b > 0) {
    if (left[0] > right[0]) {
      return [].concat(left[0], merge(left.slice(1,a), right));
    } else {
      return [].concat(right[0], merge(right.slice(1,b), left));
    }
  } else if (a == 0) {
    return right;
  } else of (b == 0)
    return left;

}


/************************************************************
 * Demonstration
 ***********************************************************/

function doSort() {
    var array = document.getElementById('in').value.split(/[, ]+/).map(function(e) {
        return parseInt(e);
    });
    var sorted = sort(array);
    document.getElementById('out').value = sorted;
}

function generateRandom(len) {
    var array = [];
    for (var i = 0; i < len; i++) {
        array.push(Math.round(Math.random() * 100));
    }
    document.getElementById('in').value = array;
};

generateRandom(20);
Run Code Online (Sandbox Code Playgroud)
<button onclick="generateRandom(20)">?? Generate random numbers ??</button>
<div><input id="in" size="80"></div>
<button onclick="doSort()">?? Sort ??</button>
<div><input id="out" size="80" disabled></div>
Run Code Online (Sandbox Code Playgroud)

最后一个条件分支else of不是else if.通常,else of应该导致语法错误.然而,无论我怎么努力,我都无法触发语法错误 - 它总是成功返回按降序排序的数组!

我知道,else of (b == 0)可能会被替换else,但我仍然想知道:这段代码怎么可能有效呢?

Ale*_*lan 4

这是因为 Javascript 的两个“坏事”的组合:在仅包含单个语句的块语句中跳过大括号,以及分号插入

如果正确支撑,您的if陈述应如下所示:

if (a > 0 && b > 0) {
    if (left[0] > right[0]) {
        return [].concat(left[0], merge(left.slice(1,a), right));
    } else {
        return [].concat(right[0], merge(right.slice(1,b), left));
    }
} else if (a == 0) {
    return right;
} else of (b == 0) {
    return left;
}
Run Code Online (Sandbox Code Playgroud)

但是,由于缺少大括号和分号插入,Javascript 会像这样查看/解析它:

if (a > 0 && b > 0) {
    if (left[0] > right[0]) {
        return [].concat(left[0], merge(left.slice(1,a), right));
    } else {
        return [].concat(right[0], merge(right.slice(1,b), left));
    }
} else if (a == 0) {
    return right;
} else {
    of(b == 0);
}

return left;
Run Code Online (Sandbox Code Playgroud)

如果您总是传入合法的leftright数组,那么永远不会到达最后一个else分支,因此您没有看到异常。

如果传入一个空right数组,它将到达最后一个分支并抛出of is not a function

merge([10, 20, 30], []);
Run Code Online (Sandbox Code Playgroud)

任何受人尊敬的编码标准都应该明确要求永远不要使用 Javascript 的这两个“功能”……但这只是一种观点。