web-dev-qa-db-ja.com

Array.prototype.Push()を拡張する方法は?

Array.Pushメソッドを拡張して、Pushを使用するとコールバックメソッドがトリガーされ、通常の配列関数が実行されるようにしようとしています。

これを行う方法はよくわかりませんが、これまでに失敗したコードをいくつか示します。

arr = [];
arr.Push = function(data){

    //callback method goes here

    this = Array.Push(data);
    return this.length;

}

arr.Push('test');
28
Geuis

Pushでは複数の要素をプッシュできるため、以下のarguments変数を使用して、実際のP​​ushメソッドにすべての引数を持たせます。

このソリューションは、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);
    };
})();
71
some

まず、サブクラス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:(protoはほとんど非推奨ですが、現時点では唯一の解決策です)

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

Array.prototype.PushはJavaScript1.2で導入されました。それは本当にこれと同じくらい簡単です:

Array.prototype.Push = function() {
    for( var i = 0, l = arguments.length; i < l; i++ ) this[this.length] = arguments[i];
    return this.length;
};

その前にいつでも何かを追加できます。

6
Jhuni

あなたはこのようにそれを行うことができます:

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

編集:

その方法を説明している間、コールバックを実行してから、Pushをオーバーライドするのではなく、配列に対してPushを呼び出す別のメソッドを使用した方がよい場合があります。予期しない副作用が発生する可能性があります。たとえば、Pushは可変的であるように見え(printfのように可変数の引数をとります)、上記を使用するとそれが壊れます。

この関数を適切にオーバーライドするには、_Arguments()と_ArgumentsLength()をいじる必要があります。私はこのルートに反対することを強くお勧めします。

もう一度編集する:または、「引数」を使用することもできますが、それも機能します。それでも、このルートを取ることはお勧めしません。

5
Patrick

私は関数を呼び出したかったafterオブジェクトが配列にプッシュされたので、次のようにしました:

myArray.Push = function() { 
    Array.prototype.Push.apply(this, arguments);
    myFunction();
    return myArray.length;
};

function myFunction() {
    for (var i = 0; i < myArray.length; i++) {
        //doSomething;
    }
}
0