Javascript 将事件侦听器附加到Push()事件的数组

Javascript 将事件侦听器附加到Push()事件的数组,javascript,dom-events,Javascript,Dom Events,有没有办法知道用户何时(通过push())将项目推送到数组中 基本上,我有一个异步脚本,允许用户将命令推送到数组上。一旦我的脚本加载,它就会执行命令。问题是,在我的脚本已经运行之后,用户可能会将其他命令推送到阵列上,并且需要在发生这种情况时通知我。请记住,这只是用户自己创建的常规数组。谷歌分析也做了类似的事情 我也发现了这一点,我认为谷歌就是这么做的,但我不太理解代码: Aa = function (k) { return Object.prototype[ha].cal

有没有办法知道用户何时(通过
push()
)将项目推送到数组中

基本上,我有一个异步脚本,允许用户将命令推送到数组上。一旦我的脚本加载,它就会执行命令。问题是,在我的脚本已经运行之后,用户可能会将其他命令推送到阵列上,并且需要在发生这种情况时通知我。请记住,这只是用户自己创建的常规数组。谷歌分析也做了类似的事情


我也发现了这一点,我认为谷歌就是这么做的,但我不太理解代码:

    Aa = function (k) {
        return Object.prototype[ha].call(Object(k)) == "[object Array]"
我还发现了一个很好的例子,它似乎涵盖了基础,但我无法让我添加的推送方法正确工作:
唯一可行的方法是编写一个围绕数组的类:

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'

未经测试,但我认为类似的方法可以奏效:

Array.prototype.push = function(e) {
    this.push(e);
    callbackFunction(e);
}
试试这个:

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);
var MyArray=function(){};
MyArray.prototype=Array.prototype;
MyArray.prototype.push=函数(){
log('push now!');
for(var i=0;i

您可以在推后或推前添加函数。更好的方法是使用这些方法修改数组长度这一事实。 利用这一点的方法非常简单(CoffeeScript):


为什么不这样做呢

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

您可以使用一个“eventify”函数来覆盖传入的数组中的push

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

这将为所有数组添加一个名为
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');

如果您想在单个阵列上执行此操作,则会提醒“somearray中现在有一个swag”:

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

出于调试目的,您可以尝试。并从调用堆栈跟踪调用函数

yourArray.push = function(){debugger;}

我会像这样将原始数组包装在一个简单的观察者界面上

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

您还可以扩展观察器以观察其他事件,如预推或后推,或在与内部基阵列交互时希望发出的任何事件。

有时您需要在回调可用之前对事件进行排队。这就解决了这个问题。将任何项推送到数组中。要开始使用这些项目后,请将数组和回调传递给
QueuedCallback()
QueuedCallback
将重载
数组。将
作为回调推送,然后循环处理所有排队的项目。继续将项目推送到该数组,它们将直接转发到回调。数组将保持为空

兼容所有浏览器和IE 5.5+

var QueuedCallback = function(arr, callback) {
  arr.push = callback;
  while (arr.length) callback(arr.shift());
};

示例用法。

用户是否通过您提供的UI创建此数组?不,它必须是一个常规数组,因为我的脚本尚未加载,所以我没有任何他们可以创建的特殊包装器对象,等等。查看array.observe()方法实际上可能没有,我正在尝试扩展内置的push。这接近我需要的,但我想知道是否有一种方法可以只在一个特定的数组上执行此操作,或者我是否可以以某种方式知道数组的id?我做了一些工作,但不确定如何确保它是我需要实际查看的一个数组:我也发现了这一点,我认为Google就是这么做的,但我不太理解代码:Aa=function(k){return Object.prototype[ha].call(Object(k))=“[Object array]”问题是我的脚本还没有加载,所以它必须是一个常规数组。我可以创建的任何特殊对象在创建数组时都没有访问权限。我也发现了这一点,我认为谷歌就是在这里做的,但我不太懂代码:Aa=function(k){return Object.prototype[ha]。call(Object(k))==”[对象数组]”或者,如果我有办法在加载脚本后将常规数组转换为特殊对象类型,然后附加特殊事件处理程序。我使用您的代码创建了一个示例,但一旦我将一个项推到数组上,该数组仍然没有项:>>我还做了一个示例,尝试交换对象,但第一个问题是阻止我使用tes非常感谢您的帮助。@KingOfHypocrites更新了我的答案,定义了一个
getArray()
method。使用此方法访问底层数组。下面是您的示例,经过修改后可以使用此方法:此示例是给定问题上下文中的完美答案。甚至可以使其更通用:
eventify=function(arr,what,callback){arr[what]=function(e){array.prototype[what].call(arr,e);callback(arr);};};let test=[];eventify(test,'push',(arr)=>{console.log(`Push1:Array has length:${arr.length});})test.push(1);test.push(2);test.push(3);
var QueuedCallback = function(arr, callback) {
  arr.push = callback;
  while (arr.length) callback(arr.shift());
};