2009-02-21 149 views
24

我想擴展Array.push方法,以便使用push將觸發一個回調方法,然後執行正常的數組函數。如何擴展Array.prototype.push()?

我不太清楚如何做到這一點,但這裏有一些我一直玩的代碼失敗。

arr = []; 
arr.push = function(data){ 

    //callback method goes here 

    this = Array.push(data); 
    return this.length; 

} 

arr.push('test'); 

回答

62

由於push允許推送多個元素,因此我使用下面的參數變量讓真正的推式方法擁有所有參數。

這種解決方案僅影響ARR變量:

arr.push = function(){ 
    //Do what you want here... 
    return Array.prototype.push.apply(this,arguments); 
} 

此溶液會影響所有的陣列。我不建議你這樣做。

Array.prototype.push=(function(){ 
    var original = Array.prototype.push; 
    return function() { 
     //Do what you want here. 
     return original.apply(this,arguments); 
    }; 
})(); 
+0

我最喜歡的函數包裝形式是在執行外部函數時傳遞Array.prototype.push,並在函數中將其作爲變量原始接受。它更簡潔一點 – pottedmeat 2009-02-21 10:04:00

+9

@pottedmeat:但它的可讀性較差 - 請記住,程序不僅是爲機器編寫的,而且也是爲其他程序員編寫的! – Christoph 2009-02-21 10:45:26

+1

@some非常感謝您對原型的一個清晰的解釋,而不是! – Dorjan 2012-06-01 17:07:50

4

你可以這樣來做:

arr = [] 
arr.push = function(data) { 
    alert(data); //callback 

    return Array.prototype.push.call(this, data); 
} 

如果您在不通話的情況下的時候,你也可以去這個解決方案:

arr.push = function(data) { 
    alert(data); //callback 

    //While unlikely, someone may be using psh to store something important 
    //So we save it. 
    var saved = this.psh; 
    this.psh = Array.prototype.push; 
    var ret = this.psh(data); 
    this.psh = saved; 
    return ret; 
} 

編輯:

雖然我告訴你如何去做,但你可能會更好地使用不同的方法執行回調,然後調用pu在陣列上而不是推翻。你可能會出現一些意想不到的副作用。例如,push似乎是可變的(採用可變數量的參數,如printf),使用上述操作會破壞這一點。

你需要弄亂_Arguments()和_ArgumentsLength()來正確覆蓋這個函數。我強烈反對這條路線。

再次編輯: 或者你可以使用「參數」,這也可以。不過建議不要採取這條路線。

+0

Array.prototype.push.call(這一點,數據);由於Array可能需要多個項目,因此無法工作。 Array.prototype.push.apply(this,arguments); – ToughPal 2015-03-03 07:46:57

-1

我這樣做:

var callback = function() { alert("called"); }; 
var original = Array.prototype.push; 
Array.prototype.push = function() 
{ 
    callback(); 
    return original.apply(this, arguments); 
}; 

如果你想要一個參數是一個回調,你可以這樣做:

var original = Array.prototype.push; 
Array.prototype.push = function(callback) 
{ 
    callback(); 
    return original.apply(this, Array.prototype.slice.call(arguments, 1)); 
} 

這些都已經過測試。

4

Array.prototype.push在JavaScript 1.2中引入。它的確如此簡單:

Array.prototype.push = function() { 
    for(var i = 0, l = arguments.length; i < l; i++) this[this.length] = arguments[i]; 
    return this.length; 
}; 

你總是可以在前面添加一些東西。

0

我想調用一個函數後的對象已被推到數組,所以我做了以下內容:

myArray.push = function() { 
    Array.prototype.push.apply(this, arguments); 
    myFunction(); 
    return myArray.length; 
}; 

function myFunction() { 
    for (var i = 0; i < myArray.length; i++) { 
     //doSomething; 
    } 
} 
1

首先,你需要繼承Array

ES6:(不兼容使用除Chrome50 +以外的babel或瀏覽器https://kangax.github.io/compat-table/es6/

class SortedArray extends Array { 
    constructor(...args) { 
     super(...args); 
    } 
    push() { 
     return super.push(arguments); 
    } 
} 

es5 :(幾乎棄用,但它是對於現在的唯一的解決方案)

function SortedArray() { 
    var arr = []; 
    arr.push.apply(arr, arguments); 
    arr.__proto__ = SortedArray.prototype; 
    return arr; 
} 
SortedArray.prototype = Object.create(Array.prototype); 

SortedArray.prototype.push = function() { 
    this.arr.push(arguments); 
};