2015-09-11 77 views
2

當這個方法被調用時,它反轉原始數組中的項目的順序。然後它返回相同的原始數組。不需要創建新陣列來傳遞這個kata。 但是,我試圖弄清楚this.push(arr.pop());在這個函數中的工作原理。試圖瞭解此函數:Array.prototype.reverse =函數(){

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(), []); 

或請寫出你認爲一個功能是一個更好的解決方案

回答

4

我添加註釋:

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()去除arr5
  4. this.push()增加5this下一個可用的位置,這是一開始
  5. arr.length現在是4,所以我們進入人體再次
  6. arr.pop()去除arr4
  7. this.push()增加4this下一個可用的位置,這是剛過5
  8. 漂洗,重複
  9. arr.length0,它不是truthy了,我們退出循環
1

「或請寫出你認爲一個功能是更好的解決方案」

這裏有一個更高效,更簡單的解決方案:

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

不知道有任何額外的開銷。