9

重複の可能性:
Javascript - Array.prototype.push() を拡張するには?

登録された配列への変更 (または少なくとも要素の追加または削除) を通知する (事前定義された関数を実行する) にはどうすればよいですか? 試作品を使ってみました。私自身のいくつかのコード例を提供していないことで叱られたくありません。では、こんな風に使いたいと思います。

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

やり過ぎはいらない。私は基本的に、使用する配列関数のスコープを知っています (push、pop、splice、およびその他のいくつか)。バックボーンのMVCを利用する方法です。配列でロジックを実行したいので、それに応じてビューを強調表示します。ただし、ビューは既にコレクションに関連付けられています。そのコレクションを変更すると、ビュー内の実際の DOM が再レンダリングされます。私はそれをしたくありません。CSS の目的で、ビュー内の対応する DOM にクラスを追加または削除したいだけです。

4

3 に答える 3

14

私がしたことは、プロトタイプ配列を拡張した独自の「配列」タイプを作成し、それに独自のハンドラーを追加したことです。

例えば:

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

    return arr;
};

使用法:

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

フィドル: http://jsfiddle.net/maniator/vF659/

于 2012-12-11T18:06:42.353 に答える
2

を探していますがObject.observe、まだ広くは利用できません。Chrome Canary では、about:flags で「Experimental JavaScript」を有効にすると、次のことを試すことができます。

​var arr = [];

​Object.observe(arr, function(changes) {
    console.log("The array changed. Changes:", changes);
});
于 2012-12-11T18:29:23.033 に答える
1

このようなものは、配列の push() のグローバル監視を設定します。

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

それ以外の場合は、ニールが提案したように、別のクラスを作成できます。

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

一度に N 個の関数呼び出しの基本的な監視をセットアップするには。

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

同様の適応は、最初の例でも機能するはずです。

于 2012-12-11T18:17:02.433 に答える