2009-02-21 148 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); 
};