试图理解这个函数:Array.prototype.reverse = function() {

Trying to understand this function: Array.prototype.reverse = function() {

调用此方法时,它会反转原始数组中项目的顺序。然后它 returns 相同的原始数组。不需要创建新数组来传递此型。 但是,我想弄清楚 this.push(arr.pop()); 在这个函数中是如何工作的。

Array.prototype.reverse = function() {
  var arr = this.splice(0);  //I understand first we remove all the items in the array starting from [0]

  while(arr.length) {    //then we run the arr.length of all the items? 
    this.push(arr.pop());  //then add the deleted last item? doesn't make sense...
  }   

  return this;
};

测试用例:

Test.assertSimilar([1, 2, 3, 4].reverse(), [4,3,2,1]);
Test.assertSimilar(["a", "b", "c"].reverse(), ["c", "b", "a"]);
Test.assertSimilar([].reverse(), []);

或者请写一个你认为更好的函数解决方案

我添加了评论:

Array.prototype.reverse = function() {
  var arr = this.splice(0);  // Removes all entries from `this` array AND returns
                             // them in a new array

  while(arr.length) {        // For as long as that new array still has items
                             // (length is "truthy" until it's 0)
    this.push(arr.pop());    // `pop` removes the LAST entry from `arr`, and
                             // `push` adds it to `this` as the next entry
  }   

  return this;
};

假设我们有 [1, 2, 3, 4, 5]:

  1. 首先从 this 中删除并放入 arr
  2. 然后,因为arr.length5,我们进入循环体
  3. arr.pop()arr.
  4. 中删除 5
  5. this.push()5 添加到 this 中的下一个可用位置,即开头
  6. arr.length现在是4,所以我们再次进入正文
  7. arr.pop()arr.
  8. 中删除 4
  9. this.push()4 添加到 this 中的下一个可用位置,就在 5
  10. 之后
  11. 冲洗,重复
  12. arr.length0时,它不再为真,我们退出循环

"or please write a function you think is a better solution"

这里有一个更有效、更简单的解决方案:

Array.prototype.reverse = function() {
  for (var i = 0, j = this.length - 1; i < j; i++, j--) {
    var tmp = this[i];
    this[i] = this[j];
    this[j] = tmp;
  }
  return this;
};

在支持 ECMAScript 6 的浏览器中,您可以将其缩短为:

Array.prototype.reverse = function() {
  for (var i = 0, j = this.length - 1; i < j; i++, j--) {
    [this[i], this[j]] = [this[j], this[i]];
  }
  return this;
};

不确定是否有任何额外开销。