سؤال

Possible Duplicate:
Javascript - How to extend Array.prototype.push()?

How can I be notified (run a pre-defined function) of any change to a registered array (or at least any addition or removal of elements)? I tried using prototype. I don't want to be scolded for not providing SOME code examples of my own. So here's how I would like to use it.

var myArray = [];
myArray.bind(function() {
    console.log('wtf'); // Wed Thu Fri and what were you thinking?
});

I don't need overkill. I basically know the Array function scope that I will be using (push, pop, splice and maybe a couple others). It's a way to use backbone's MVC. I want to run logic on an array and THEN have the views highlighted accordingly. But the view is already attached to a collection. Any change to that collection re-renders the actual DOM's in the view. I don't want that. I simple want to add, or remove, a class to the corresponding DOM's in the view for CSS purposes.

هل كانت مفيدة؟

المحلول

What I did is I made my own "array" type that just extended the prototype array, which then I added my own handlers to.

For example:

var MyArray = function() {
    var arr = [];
    arr.push = function() {
        console.log("PUSHING", arguments);
        return Array.prototype.push.apply(this, arguments);
    }

    return arr;
};

Usage:

var arr = new MyArray;
arr.push(12, 3, 45);
...

Fiddle: http://jsfiddle.net/maniator/vF659/

نصائح أخرى

You're looking for Object.observe, but it's not widely available yet. In Chrome Canary, with "Experimental JavaScript" enabled on about:flags you can try the following:

​var arr = [];

​Object.observe(arr, function(changes) {
    console.log("The array changed. Changes:", changes);
});

Something like this will set up global monitoring of array push()'s.

(function() {
  var _push = Array.prototype.push;
  Array.prototype.push = function() {
    console.log("push");
    return _push.apply(this, arguments);
  }
})();

Otherwise, as Neal suggested, you can create another class.

var MonitoredArray = function() {
  var rv = [];
  var _push = rv.push;
  rv.push = function() {
    console.log("push()");
    console.log(arguments);
    return _push.apply(this, arguments);
  }
  return rv;
}

To set up basic monitoring of N function calls at once.

var MonitoredArray = function() {
  var rv = [];

  // the names of the functions we want to log:
  var logged_fns = ["push", "pop"];

  for (var i in logged_fns) { (function() {
    var name = logged_fns[i]
    var fn = rv[name];

    rv[name] = function() {
      console.log(name + "()");
      console.log(arguments);
      return fn.apply(rv, arguments);
    }
  })()}

  return rv;
}

A similar adaptation should work for the first example too.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top