Javascript 如果我使用pre-2015方法在函数中声明参数默认值,则快速排序无限循环,但如果使用ES2015默认参数值,则效果良好

Javascript 如果我使用pre-2015方法在函数中声明参数默认值,则快速排序无限循环,但如果使用ES2015默认参数值,则效果良好,javascript,ecmascript-6,parameters,quicksort,default-parameters,Javascript,Ecmascript 6,Parameters,Quicksort,Default Parameters,我一直在尝试实现一个快速排序功能,并使一切工作。但有一个特点是我无法理解或理解其原因 在第一段代码中,您将看到我为quickSort()函数声明了一些默认参数值: function swap(arr, firstIndex, secondIndex) { let temp = arr[firstIndex]; arr[firstIndex] = arr[secondIndex]; arr[secondIndex] = temp; } function pivot(arr, star

我一直在尝试实现一个快速排序功能,并使一切工作。但有一个特点是我无法理解或理解其原因

在第一段代码中,您将看到我为
quickSort()
函数声明了一些默认参数值:

function swap(arr, firstIndex, secondIndex) {
  let temp = arr[firstIndex];
  arr[firstIndex] = arr[secondIndex];
  arr[secondIndex] = temp;
}

function pivot(arr, start = 0, end = arr.length - 1) {
  // We are assuming that the pivot is always the first element
  let pivot = arr[start];
  let swapIndex = start;

  for (let i = start + 1; i <= end; i++) {
    if (pivot > arr[i]) {
      swapIndex++;
      swap(arr, swapIndex, i);
    }
  }

  // Swap the starting element with the pivot index
  swap(arr, start, swapIndex);
  return swapIndex;
}

function quickSort(arr, left = 0, right = arr.length - 1) {
  if (left < right) {
    let pivotIndex = pivot(arr, left, right);
    // left
    quickSort(arr, left, pivotIndex - 1);
    // right
    quickSort(arr, pivotIndex + 1, right);
  }
  return arr;
}
我遇到了无限循环/堆栈溢出问题,我无法理解原因。据我所知,问题是由第三个参数引起的-
right
-而不是left param,因为如果我使用es2015之前的方法调用left param,而使用es2015 param default方法保留
right
param,代码工作正常

总而言之,我的代码工作正常,所以这很好-我只是想尝试更好地理解为什么这会导致问题,因为我以前从未遇到过这样的问题


谢谢

问题是当
0
作为
right
传递时,两个版本的工作方式不同。(因为这是一个基本情况,所以得到了一个无限循环)

当传入
0
时计算到右侧,因为
0
无效

另一方面,如果传入
0
,则默认参数初始化器将
0
置于
右侧
,并且仅当传入
未定义
(或根本没有参数)时,才计算
arr.length-1
表达式

要复制这种行为,请在ES5中编写

function quickSort(arr, left, right) {
  if (left === undefined) left = 0;
  if (right === undefined) right = arr.length - 1;
  if (left < right) {
    let pivotIndex = pivot(arr, left, right);
    // left
    quickSort(arr, left, pivotIndex - 1);
    // right
    quickSort(arr, pivotIndex + 1, right);
  }
  return arr;
}
函数快速排序(arr、左、右){
如果(left==未定义)left=0;
如果(right==未定义)right=arr.length-1;
if(左<右){
让pivotIndex=pivot(arr,左,右);
//左
快速排序(arr,左,数据透视索引-1);
//对
快速排序(arr,数据透视索引+1,右);
}
返回arr;
}

问题在于,当
0
作为
right
传递时,两个版本的工作方式不同。(因为这是一个基本情况,所以得到了一个无限循环)

当传入
0
时计算到右侧,因为
0
无效

另一方面,如果传入
0
,则默认参数初始化器将
0
置于
右侧
,并且仅当传入
未定义
(或根本没有参数)时,才计算
arr.length-1
表达式

要复制这种行为,请在ES5中编写

function quickSort(arr, left, right) {
  if (left === undefined) left = 0;
  if (right === undefined) right = arr.length - 1;
  if (left < right) {
    let pivotIndex = pivot(arr, left, right);
    // left
    quickSort(arr, left, pivotIndex - 1);
    // right
    quickSort(arr, pivotIndex + 1, right);
  }
  return arr;
}
函数快速排序(arr、左、右){
如果(left==未定义)left=0;
如果(right==未定义)right=arr.length-1;
if(左<右){
让pivotIndex=pivot(arr,左,右);
//左
快速排序(arr,左,数据透视索引-1);
//对
快速排序(arr,数据透视索引+1,右);
}
返回arr;
}
常量快速排序=([x,…rest])=>(!x | | x==未定义)?[]:快速排序(rest.filter(a=>aa>=x)))`
很抱歉,这是
ECMAScript 6
而不是
es5

const quicksort=([x,…rest])=>(!x | | x==未定义)?[]:快速排序(rest.filter(a=>aa>=x)))`

很抱歉,这是
ECMAScript 6
而不是
es5

如果将
0
传递给第三个参数,则在第二个版本中将其更改为
arr.length-1
,而在第一个版本中则不是。默认值是在未传递任何参数时使用-当参数为任何错误(如0)时,代码使用默认值。。。要编写与ES2015相同的代码,您需要检查参数的长度,而不是值。如果将
0
传递给第三个参数,则在第二个版本中将其更改为
arr.length-1
,而在第一个版本中则不是这样。默认值是在未传递任何参数时使用-当参数为任何错误(如0)时,代码使用默认值。。。要编写与ES2015相同的代码,您需要检查参数的长度,而不是值。只是用您的更改测试了代码,它工作得非常好-感谢您的教育好先生!刚刚用您的更改测试了代码,它工作得非常完美-谢谢您的教育好先生!
function quickSort(arr, left, right) {
  if (left === undefined) left = 0;
  if (right === undefined) right = arr.length - 1;
  if (left < right) {
    let pivotIndex = pivot(arr, left, right);
    // left
    quickSort(arr, left, pivotIndex - 1);
    // right
    quickSort(arr, pivotIndex + 1, right);
  }
  return arr;
}