Как расширить 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');
Ответы
Ответ 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));
}
Оба они были протестированы.