Подтвердить что ты не робот

Как расширить 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');
4b9b3361

Ответ 1

Поскольку push позволяет переносить более одного элемента, я использую переменную ниже, чтобы позволить действительному методу push все аргументы.

Это решение влияет только на переменную 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);
    };
})();

Ответ 2

Сначала вам нужен подкласс Array:

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

Ответ 3

Array.prototype.push был введен в JavaScript 1.2. Это действительно так просто:

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

Вы всегда можете добавить что-то впереди.

Ответ 4

Вы можете сделать это следующим образом:

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

Edit:

Пока я рассказываю вам, как это сделать, вам лучше использовать другой метод, который выполняет обратный вызов, а затем просто нажимает на массив, а не переопределяет push. Вы можете столкнуться с неожиданными побочными эффектами. Например, push выглядит как varadic (принимает переменное количество аргументов, например printf), и использование вышеизложенного нарушит это.

Вам нужно будет беспорядок с _Arguments() и _ArgumentsLength(), чтобы правильно переопределить эту функцию. Я настоятельно рекомендую против этого маршрута.

Изменить еще раз: Или вы можете использовать "аргументы", это тоже сработает. Тем не менее советуйте не принимать этот маршрут.

Ответ 5

Я хотел вызвать функцию после, объект был перенесен в массив, поэтому я сделал следующее:

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

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

Ответ 6

Я бы сделал это:

var callback = function() { alert("called"); };
var original = Array.prototype.push;
Array.prototype.push = function()
{
  callback();
  return original.apply(this, arguments);
};

Если вы хотите, чтобы аргумент был обратным вызовом, вы можете сделать это:

var original = Array.prototype.push;
Array.prototype.push = function(callback)
{
  callback();
  return original.apply(this, Array.prototype.slice.call(arguments, 1));
}

Оба они были протестированы.