有没有办法知道用户何时(通过push())将项目推送到数组?
基本上我有一个异步脚本,允许用户将命令推送到数组上。加载脚本后,它会执行命令。问题是,用户可能会在我的脚本运行后将其他命令推送到阵列上,我需要在发生这种情况时收到通知。请记住,这只是用户自己创建的常规数组。 Google Analytics(分析)会做与此类似的事情。
我也发现这是我认为谷歌所做的,但我不太了解代码:Aa = function(k){ return Object.prototype [ha] .call(Object(k))==“[object Array]”
我还找到了一个很好的例子,似乎涵盖了基础,但我无法让我添加的推送方法正常工作: http://jsbin.com/ixovi4/4/edit
答案 0 :(得分:24)
你可以使用' eventify'覆盖推送传递数组的函数。
var eventify = function(arr, callback) {
arr.push = function(e) {
Array.prototype.push.call(arr, e);
callback(arr);
};
};
在下面的示例中,应该引发3个警报,因为这是事件处理程序(回调)在调用eventify之后所做的事情。
var testArr = [1, 2];
testArr.push(3);
eventify(testArr, function(updatedArr) {
alert(updatedArr.length);
});
testArr.push(4);
testArr.push(5);
testArr.push(6);
答案 1 :(得分:22)
唯一明智的做法是编写一个包装数组的类:
function EventedArray(handler) {
this.stack = [];
this.mutationHandler = handler || function() {};
this.setHandler = function(f) {
this.mutationHandler = f;
};
this.callHandler = function() {
if(typeof this.mutationHandler === 'function') {
this.mutationHandler();
}
};
this.push = function(obj) {
this.stack.push(obj);
this.callHandler();
};
this.pop = function() {
this.callHandler();
return this.stack.pop();
};
this.getArray = function() {
return this.stack;
}
}
var handler = function() {
console.log('something changed');
};
var arr = new EventedArray(handler);
//or
var arr = new EventedArray();
arr.setHandler(handler);
arr.push('something interesting'); //logs 'something changed'
答案 2 :(得分:13)
试试这个:
var MyArray = function() { };
MyArray.prototype = Array.prototype;
MyArray.prototype.push = function() {
console.log('push now!');
for(var i = 0; i < arguments.length; i++ ) {
Array.prototype.push.call(this, arguments[i]);
}
};
var arr = new MyArray();
arr.push(2,3,'test',1);
您可以在推后或推送之前添加功能
答案 3 :(得分:3)
为什么不做这样的事情?
Array.prototype.eventPush = function(item, callback) {
this.push(item);
callback(this);
}
然后定义一个处理程序。
handler = function(array) {
console.log(array.length)
}
然后在希望特定事件发生的地方使用eventPush,如下所示:
a = []
a.eventPush(1, handler);
a.eventPush(2, handler);
答案 4 :(得分:2)
我将原始数组包装在一个简单的观察者界面周围。
function EventedList(list){
this.listbase = list;
this.events = [];
}
EventedList.prototype.on = function(name, callback){
this.events.push({
name:name,
callback:callback
});
}
//push to listbase and emit added event
EventedList.prototype.push = function(item){
this.listbase.push(item);
this._emit("added", item)
}
EventedList.prototype._emit = function(evtName, data){
this.events.forEach(function(event){
if(evtName === event.name){
event.callback.call(null, data, this.listbase);
}
}.bind(this));
}
然后我用基数组
实例化它 //returns an object interface that lets you observe the array
var evtList = new EventedList([]);
//attach a listener to the added event
evtList.on('added', function(item, list){
console.log("added event called: item = "+ item +", baseArray = "+ list);
})
evtList.push(1) //added event called: item = 1, baseArray = 1
evtList.push(2) //added event called: item = 2, baseArray = 1,2
evtList.push(3) //added event called: item = 3, baseArray = 1,2,3
您还可以扩展观察者以观察其他内容,例如prePush或postPush,或者当您与内部基本阵列交互时要发出的任何事件。
答案 5 :(得分:1)
这将为所有数组添加一个名为onPush
的函数,默认情况下它不应该执行任何操作,因此它不会干扰正常运行的数组。
只需覆盖单个数组上的onPush
。
Array.prototype.oldPush = Array.prototype.push;
Array.prototype.push = function(obj){
this.onPush(obj);
this.oldPush(obj);
};
//Override this method, be default this shouldnt do anything. As an example it will.
Array.prototype.onPush = function(obj){
alert(obj + 'got pushed');
};
//Example
var someArray = [];
//Overriding
someArray.onPush = function(obj){
alert('somearray now has a ' + obj + ' in it');
};
//Testing
someArray.push('swag');
此警告&#39; somearray现在有一个蠢货&#39;
答案 6 :(得分:1)
有时您需要在回调可用之前排队。这解决了这个问题。将任何项目推送到数组。一旦您想开始使用这些项目,请将数组和回调传递给QueuedCallback()
。 QueuedCallback
将重载array.push
作为您的回调,然后循环浏览任何排队的项目。继续将项目推送到该阵列,它们将直接转发到您的回调。该数组将保持为空。
兼容所有浏览器和IE 5.5 +。
var QueuedCallback = function(arr, callback) {
arr.push = callback;
while (arr.length) callback(arr.shift());
};
示例用法here。
答案 7 :(得分:0)
未经测试,但我假设这样的事情可行:
Array.prototype.push = function(e) {
this.push(e);
callbackFunction(e);
}
答案 8 :(得分:0)
更好的方法是使用这些方法修改数组长度的事实。 利用它的方法非常简单(CoffeeScript):
class app.ArrayModelWrapper extends Array
constructor: (arr,chName,path)->
vl = arr.length
@.push.apply(@,arr)
Object.defineProperty(@,"length",{
get: ->vl
set: (newValue)=>
console.log("Hello there ;)")
vl = newValue
vl
enumerable: false
})
答案 9 :(得分:0)
如果你想在一个阵列上这样做:
var a = [];
a.push = function(item) {
Array.prototype.push.call(this, item);
this.onPush(item);
};
a.onPush = function(obj) {
// Do your stuff here (ex: alert(this.length);)
};
答案 10 :(得分:0)
出于调试目的,您可以尝试。并从调用堆栈中跟踪调用函数。
yourArray.push = function(){debugger;}