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

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

本文关键字:reverse prototype function Array 函数      更新时间:2023-09-26

当调用此方法时,它将反转原始数组中项的顺序。然后它返回原来的那个数组。不需要创建新的数组来传递此类型。然而,我正试图弄清楚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()5arr中移除
  4. this.push()5添加到this的下一个可用位置,即
  5. arr.length现在是4,所以我们再次进入body
  6. arr.pop()4arr中移除
  7. this.push()4添加到this的下一个可用位置,就在5之后
  8. 冲洗,重复
  9. arr.length0时,它不再为真,我们退出循环

"或者写一个你认为更好的函数"

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

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;
};

不确定是否有额外的开销