Javascript: move objects from one array to another: Best approach? - javascript

I have two arrays, called 'objects' and 'appliedObjects'. I'm trying to come up with an elegant way in Javascript and/or Angular to move objects from one array to another.
Initially I did something like this:
$scope.remove = function () {
angular.forEach($scope.appliedObjects, function (element, index) {
if (element.selected) {
element.selected = false;
$scope.objects.push(element);
$scope.appliedObjects.splice(index, 1);
}
});
}
$scope.add= function () {
angular.forEach($scope.objects, function (element, index) {
if (element.selected) {
element.selected = false;
$scope.appliedObjects.push(element);
$scope.objects.splice(index, 1);
}
});
}
But then I realized that when the value was removed from the looping array, and it would not add or remove every other item, since it went by index.
Then I tried using a temporary array to hold the list of items to be added or removed, and I started getting strange referential issues.
I'm starting to spin a bit on what the best solution to this problem would be...any help and/or guidance would much appreciated.

function moveElements(source, target, moveCheck) {
for (var i = 0; i < source.length; i++) {
var element = source[i];
if (moveCheck(element)) {
source.splice(i, 1);
target.push(element);
i--;
}
}
}
function selectionMoveCheck(element) {
if (element.selected) {
element.selected = false;
return true;
}
}
$scope.remove = function () {
moveElements($scope.appliedObjects, $scope.objects, selectionMoveCheck);
}
$scope.add = function () {
moveElements($scope.objects, $scope.appliedObjects, selectionMoveCheck);
}

When a construct does too much automatically (like forEach, or even a for-loop, in this case), use a more primitive construct that allows you to say what should happen clearly, without need to work around the construct. Using a while loop, you can express what needs to happen without resorting to backing up or otherwise applying workarounds:
function moveSelected(src, dest) {
var i = 0;
while ( i < src.length ) {
var item = src[i];
if (item.selected) {
src.splice(i,1);
dest.push(item);
}
else i++;
}
}

You are altering the array while iterating on it, you will always miss some elements.
One way of doing it would be to use a third array to store the references of the objects that need to be removed from the array:
// "$scope.add" case
var objectsToRemove = [];
$scope.objects.forEach(function (value) {
if (value.selected) {
value.selected = false;
$scope.appliedObjects.push(value);
objectsToRemove.push(value);
}
});
objectsToRemove.forEach(function (value) {
$scope.objects.splice($scope.objects.indexOf(value), 1);
});

If you wish to move simply whole array you could do:
appliedObjects = objects;
objects = []
Of course it won't work if they were parameters of a function!
Otherwise I cannot see other way than copying in the loop, e.g.
while (objects.length) {
appliedObjects.push(objects[0]);
objects.splice(0,1);
}
or if you like short code :) :
while (objects.length) appliedObjects.push(objects.splice(0,1));
check fiddle http://jsfiddle.net/060ywajm/

Now this maybe is not a fair answer, but if you notice you are doing alot of complicated object/array manipulations, you should really check out lodash or underscore library. then you could solve this with on liner:
//lodash remove function
appliedObjects.push.apply( appliedObjects, _.remove(objects, { 'selected': true}));
//or if you want to insert in the beginning of the list:
appliedObjects.splice(0, 0, _.remove(objects, { 'selected': true}));

This is a first pass at what I think will work for you. I'm in the process of making a test page so that I can test the accuracy of the work and will update the tweaked result, which hopefully there will not be.
EDIT: I ran it and it seems to do what you are wanting if I understand the problem correctly. There were a couple of syntax errors that I edited out.
Here's the plunk with the condensed, cleaned code http://plnkr.co/edit/K7XuMu?p=preview
HTML
<button ng-click="transferArrays(objects, appliedObjects)">Add</button>
<button ng-click="transferArrays(appliedObjects, objects)">Remove</button>
JS
$scope.transferArrays = function (arrayFrom, arrayTo) {
var selectedElements;
selectedElements = [];
angular.forEach(arrayFrom, function(element) {
if (element.isSelected) {
element.isSelected = false;
selectedElements.push(element);
}
});
angular.forEach(selectedElements, function(element) {
arrayTo.push(arrayFrom.splice(
arrayFrom.map(function(x) {
return x.uniqueId;
})
.indexOf(element.uniqueId), 1));
});
};
Old code
$scope.remove = function () {
var selectedElements;
selectedElements = [];
angular.forEach($scope.appliedObjects, function (element) {
if (element.isSelected) {
element.isSelected = false;
selectedElements.push(element);
}
});
angular.forEach(selectedElements, function (element) {
$scope.objects.push($scope.appliedObjects.splice(
$scope.appliedObjects.map(function (x) { return x.uniqueId; })
.indexOf(element.uniqueId), 1));
});
};
$scope.add = function () {
var selectedElements;
selectedElements = [];
angular.forEach($scope.objects, function (element) {
if (element.isSelected) {
element.isSelected = false;
selectedElements.push(element);
}
});
angular.forEach(selectedElements, function (element) {
$scope.appliedObjects.push($scope.objects.splice(
$scope.objects.map(function (x) { return x.uniqueId; })
.indexOf(element.uniqueId), 1));
});
};

You can use this oneliner as many times as many items you need to move from arr1 to arr2 just prepare check func
arr2.push(arr1.splice(arr1.findIndex(arr1El => check(arr1El)),1)[0])

You can use this to concat 2 arrays:
let array3 = [...array1, ...array2];

Related

Why Is This For Loop Not Changing My Array of Objects? JS

Simple question, I am sure that I am being stupid and it is an easy fix. Have an array of objects and want to access each object's vis value and change it through my for loop. I don't understand why it doesn't work.
onSearch = keyWord => {
let newMarkers = this.state.markers;
for (let i = 0; i<this.state.markers.length;i++) {
if (this.state.markers[i].name.toLowerCase().includes(keyWord.toLowerCase())) {
newMarkers[i].vis = true;
} else {
newMarkers[i].vis = false;
}
}
console.log(newMarkers);
//console.log to see if the vis value has been changed: spoiler alert it hasn't :(
this.setState({markers: newMarkers});
console.log(this.state.markers)
}
setState is asynchronous. Therefore you need to write the code as follows:
onSearch = keyWord => {
let newMarkers = this.state.markers;
for (let i = 0; i<this.state.markers.length;i++) {
if (this.state.markers[i].name.toLowerCase().includes(keyWord.toLowerCase())) {
newMarkers[i].vis = true;
} else {
newMarkers[i].vis = false;
}
}
console.log(newMarkers);
this.setState({markers: newMarkers}, () => {
// use this callback function to do stuff AFTER state changes
console.log(this.state.markers);
});
}
It keeps the state unchanged in your case. To overcome you might adapt a quick fix to this. Follow the code.
const jsonNewMarkers = JSON.stringify(newMarkers);
this.setState({markers: JSON.parse(jsonNewMarkers)}, () => {
// use this callback function to do stuff AFTER state changes
console.log(this.state.markers);
});
And please try the solution and let me know. It should work as mine it works.

Needing some visitor-like design pattern

I will give you a sample example of my problem to remove the logical complexity and let you be focus on the important part. Of course, this example will be a bit useless...
I have a tree structure where node are like that
{
path: "...",
childs : []
}
Now, I have to write all the full paths from root to each leaf in an array.
My design is very poor:
function listPaths(node) {
var result = [];
function listForNode(n, parentFullPath) {
var thisPath = parentFullPath + "/" + n.path;
result.push(thisPath);
n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}
listForNode(node, "");
return result;
}
It could be nice but I can't write the test with Mocha without having an insane 600 line code test file. At this moment, you should be asking why. The reason is the complexity of the real purpose, that's not relevant for my question. My goal is to having something 'mockable' cause I'm used to. (Java dev). But I fail.
Do you have any pattern that I can use to resolve this one? I'm not really good at JS patterns. :/
Visitor? Making an Y Combinator? So many possibility...
Thank you for reading me
You need to remember that functions are first class citizens in javascript.
I see that essentially what you have is something like
function createVisitor(parentsAccumulatorInitialValue, parentsAccumulator){
var visitor = function myVisitor (node) {
var result;
function listForNode(n, parentsAcc) {
var thisPath = parentsAccumulator(parentsAcc, n);
result.push(thisPath);
n.childs && n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}
result = [];
listForNode(node, parentsAccumulatorInitialValue());
return result;
}
return visitor;
}
var listPaths = createVisitor(
function parentInit () {
return "";
},
function parentAcc (parentFullPath, n) {
return parentFullPath + "/" + n.path;
});
But that's not the only abstraction you could take care of:
function createVisitor2(
totalAccumulatorInitialValue,
totalAccumulator,
parentsAccumulatorInitialValue,
parentsAccumulator){
var visitor = function myVisitor (node) {
var total;
function listForNode(n, parentsAcc) {
var thisPath = parentsAccumulator(parentsAcc, n);
total = totalAccumulator(total, thisPath, n);
n.childs && n.childs.forEach(function (child) {
listForNode(child, thisPath);
});
}
total = totalAccumulatorInitialValue();
listForNode(node, parentsAccumulatorInitialValue());
return total;
}
return visitor;
}
var listPaths2 = createVisitor2(
function totalInit() {
return [];
},
function totalAcc(total, thisPath, n){
total.push(thisPath);
return total;
},
function parentInit () {
return "";
},
function parentAcc (parentFullPath, n) {
return parentFullPath + "/" + n.path;
});
Which might be pretty reasonable, but as you can see, I'm already beginning to have trouble finding appropriate names for these variables. In fact, I'd say the name of our function is bad, as doesn't create anything strictly like a visitor object I know of. However, it does work (BTW, I've slightly modified it to handle nulls as well as empty arrays):
> listPaths( { path:"foo",
childs: [{path:"bar", childs: null}, {path:"bob", childs: null}]})
["/foo", "/foo/bar", "/foo/bob"]
It can be modified even further so that your trees don't strictly even have the same structure... but we're already at 4 parameters, which isn't great. It'd be better if your visitor creator were passed a single extensible object with all the necessary methods or values. For instance, maybe (pseudocode):
function createVisitor3(opts) {
//assume we've defined GetDefaults() somewhere local to createVisitor3
// as well as assume that extend is defined somewhere that copies properties
// into a new object like various previously existing libraries do.
opts = extend({}, GetDefaults(), opts);
var totalAccumulatorInitialValue = opts.totalAccumulatorInitialValue;
var totalAccumulator = opts.totalAccumulator;
var parentsAccumulatorInitialValue = opts.parentsAccumulatorInitialValue;
var parentsAccumulator = opts.parentsAccumulator;
var childrenGetter = opts.childrenGetter;
/// etc.
...
}

Can I shrink this code with an array or loop?

Forgive me, I hope this question isn't too obvious, I'm a javascript noob.
I have javascript code that takes numbers from an xml sheet and displays them in td elements on an html page. It works but I think it could be condensed into an array or a loop to be more efficient.
Is there a better way to write this code?
window.onload=function displayPrices()
{
twentyFourK=(x[i].getElementsByTagName("twentyFourK")[0].childNodes[0].nodeValue);
document.getElementById("twentyFourK").innerHTML=toCurrency(twentyFourK);
oneOzGold=(x[i].getElementsByTagName("oneOzGold")[0].childNodes[0].nodeValue);
document.getElementById("oneOzGold").innerHTML=toCurrency(oneOzGold);
fiveOzGold=(x[i].getElementsByTagName("fiveOzGold")[0].childNodes[0].nodeValue);
document.getElementById("fiveOzGold").innerHTML=toCurrency(fiveOzGold);
tenOzGold=(x[i].getElementsByTagName("tenOzGold")[0].childNodes[0].nodeValue);
document.getElementById("tenOzGold").innerHTML=toCurrency(tenOzGold);
oneKiloGold=(x[i].getElementsByTagName("oneKiloGold")[0].childNodes[0].nodeValue);
document.getElementById("oneKiloGold").innerHTML=toCurrency(oneKiloGold);
//etc.
}
Yes, a function could make things much easier for you:
window.onload = function() {
function loadCurrency(name) {
document.getElementById(name).innerHTML = toCurrency(x[i].getElementsByTagName(name)[0].firstChild.nodeValue);
}
loadCurrency('twentyFourK');
loadCurrency('oneOzGold');
loadCurrency('fiveOzGold');
loadCurrency('tenOzGold');
loadCurrency('oneKiloGold');
};
Also, if you have many items to load:
window.onload = function() {
function loadCurrency(name) {
document.getElementById(name).innerHTML = toCurrency(x[i].getElementsByTagName(name)[0].firstChild.nodeValue);
}
var items = ['twentyFourK', 'oneOzGold', 'fiveOzGold', 'tenOzGold', 'oneKiloGold'];
items.forEach(loadCurrency);
};
That requires Array.forEach, which is only available in ECMAScript 5, so here's a fallback:
Array.prototype.forEach = function(action, thisArg) {
for(var i = 0, l = this.length; i < l; i++) {
if(i in this) {
action.call(thisArg, this[i], i, this);
}
}
};
I would place the currency setting into its own method. This will be cleaner visually and will also allow for implementation changes in the future:
window.onload = function displayPrices() {
SetCurrency("twentyFourK");
SetCurrency("oneOzGold");
//etc.
}
function SetCurrency(name) {
var elements = x[i].getElementsByTagName(name);
if ((elements != null) && (elements.length != 0)) {
elements[0].innerHTML = toCurrency(elements[0].childNodes[0].nodeValue);
}
}
You could create a function with a list of element in parameter, and you just have to create a loop going through your list of elements (twentyFourK, oneKiloGold and so on)

Javascript Array of Functions

var array_of_functions = [
first_function('a string'),
second_function('a string'),
third_function('a string'),
forth_function('a string')
]
array_of_functions[0];
That does not work as intended because each function in the array is executed when the array is created.
What is the proper way of executing any function in the array by doing:
array_of_functions[0]; // or, array_of_functions[1] etc.
Thanks!
var array_of_functions = [
first_function,
second_function,
third_function,
forth_function
]
and then when you want to execute a given function in the array:
array_of_functions[0]('a string');
I think this is what the original poster meant to accomplish:
var array_of_functions = [
function() { first_function('a string') },
function() { second_function('a string') },
function() { third_function('a string') },
function() { fourth_function('a string') }
]
for (i = 0; i < array_of_functions.length; i++) {
array_of_functions[i]();
}
Hopefully this will help others (like me 20 minutes ago :-) looking for any hint about how to call JS functions in an array.
Without more detail of what you are trying to accomplish, we are kinda guessing. But you might be able to get away with using object notation to do something like this...
var myFuncs = {
firstFunc: function(string) {
// do something
},
secondFunc: function(string) {
// do something
},
thirdFunc: function(string) {
// do something
}
}
and to call one of them...
myFuncs.firstFunc('a string')
I would complement this thread by posting an easier way to execute various functions within an Array using the shift() Javascript method originally described here
var a = function(){ console.log("this is function: a") }
var b = function(){ console.log("this is function: b") }
var c = function(){ console.log("this is function: c") }
var foo = [a,b,c];
while (foo.length){
foo.shift().call();
}
Or just:
var myFuncs = {
firstFun: function(string) {
// do something
},
secondFunc: function(string) {
// do something
},
thirdFunc: function(string) {
// do something
}
}
It's basically the same as Darin Dimitrov's but it shows how you could use it do dynamically create and store functions and arguments.
I hope it's useful for you :)
var argsContainer = ['hello', 'you', 'there'];
var functionsContainer = [];
for (var i = 0; i < argsContainer.length; i++) {
var currentArg = argsContainer[i];
functionsContainer.push(function(currentArg){
console.log(currentArg);
});
};
for (var i = 0; i < functionsContainer.length; i++) {
functionsContainer[i](argsContainer[i]);
}
up above we saw some with iteration. Let's do the same thing using forEach:
var funcs = [function () {
console.log(1)
},
function () {
console.log(2)
}
];
funcs.forEach(function (func) {
func(); // outputs 1, then 2
});
//for (i = 0; i < funcs.length; i++) funcs[i]();
Ah man there are so many weird answers...
const execute = (fn) => fn()
const arrayOfFunctions = [fn1, fn2, fn3]
const results = arrayOfFunctions.map(execute)
or if you want to sequentially feed each functions result to the next:
compose(fn3, fn2, fn1)
compose is not supported by default, but there are libraries like ramda, lodash, or even redux which provide this tool
This is correct
var array_of_functions = {
"all": function(flag) {
console.log(1+flag);
},
"cic": function(flag) {
console.log(13+flag);
}
};
array_of_functions.all(27);
array_of_functions.cic(7);
If you're doing something like trying to dynamically pass callbacks you could pass a single object as an argument. This gives you much greater control over which functions you want to you execute with any parameter.
function func_one(arg) {
console.log(arg)
};
function func_two(arg) {
console.log(arg+' make this different')
};
var obj = {
callbacks: [func_one, func_two],
params: ["something", "something else"];
};
function doSomething(obj) {
var n = obj.counter
for (n; n < (obj.callbacks.length - obj.len); n++) {
obj.callbacks[n](obj.params[n]);
}
};
obj.counter = 0;
obj.len = 0;
doSomething(obj);
//something
//something else make this different
obj.counter = 1;
obj.len = 0;
doSomething(obj);
//something else make this different
Execution of many functions through an ES6 callback 🤗
const f = (funs) => {
funs().forEach((fun) => fun)
}
f(() => [
console.log(1),
console.log(2),
console.log(3)
])
Using ES6 syntax, if you need a "pipeline" like process where you pass the same object through a series of functions (in my case, a HTML abstract syntax tree), you can use for...of to call each pipe function in a given array:
const setMainElement = require("./set-main-element.js")
const cacheImages = require("./cache-images.js")
const removeElements = require("./remove-elements.js")
let htmlAst = {}
const pipeline = [
setMainElement,
cacheImages,
removeElements,
(htmlAst) => {
// Using a dynamic closure.
},
]
for (const pipe of pipeline) {
pipe(htmlAst)
}
A short way to run 'em all:
[first_function, ..., nth_function].forEach (function(f) {
f('a string');
});
the probleme of these array of function are not in the "array form" but in the way these functions are called... then...
try this.. with a simple eval()...
array_of_function = ["fx1()","fx2()","fx3()",.."fxN()"]
var zzz=[];
for (var i=0; i<array_of_function.length; i++)
{ var zzz += eval( array_of_function[i] ); }
it work's here, where nothing upper was doing the job at home...
hopes it will help
Using Function.prototype.bind()
var array_of_functions = [
first_function.bind(null,'a string'),
second_function.bind(null,'a string'),
third_function.bind(null,'a string'),
forth_function.bind(null,'a string')
]
I have many problems trying to solve this one... tried the obvious, but did not work. It just append an empty function somehow.
array_of_functions.push(function() { first_function('a string') });
I solved it by using an array of strings, and later with eval:
array_of_functions.push("first_function('a string')");
for (var Func of array_of_functions) {
eval(Func);
}
maybe something like this would do the trick:
[f1,f2,f3].map((f) => f('a string'))
Maybe it can helps to someone.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.manager = {
curHandler: 0,
handlers : []
};
manager.run = function (n) {
this.handlers[this.curHandler](n);
};
manager.changeHandler = function (n) {
if (n >= this.handlers.length || n < 0) {
throw new Error('n must be from 0 to ' + (this.handlers.length - 1), n);
}
this.curHandler = n;
};
var a = function (n) {
console.log("Handler a. Argument value is " + n);
};
var b = function (n) {
console.log("Handler b. Argument value is " + n);
};
var c = function foo(n) {
for (var i=0; i<n; i++) {
console.log(i);
}
};
manager.handlers.push(a);
manager.handlers.push(b);
manager.handlers.push(c);
</script>
</head>
<body>
<input type="button" onclick="window.manager.run(2)" value="Run handler with parameter 2">
<input type="button" onclick="window.manager.run(4)" value="Run handler with parameter 4">
<p>
<div>
<select name="featured" size="1" id="item1">
<option value="0">First handler</option>
<option value="1">Second handler</option>
<option value="2">Third handler</option>
</select>
<input type="button" onclick="manager.changeHandler(document.getElementById('item1').value);" value="Change handler">
</div>
</p>
</body>
</html>
This answered helped me but I got stuck trying to call each function in my array a few times. So for rookies, here is how to make an array of functions and call one or all of them, a couple different ways.
First we make the array.
let functionsArray = [functionOne, functionTwo, functionThree];
We can call a specific function in the array by using its index in the array (remember 0 is the first function in the array).
functionsArray[0]();
We have to put the parenthesis after because otherwise we are just referencing the function, not calling it.
If you wanted to call all the functions we could use a couple different ways.
For loop
for (let index = 0; index < functionsArray.length; index++) {
functionsArray[index]();
}
Don't forget the parenthesis to actually call the function.
ForEach
ForEach is nice because we don't have to worry about the index, we just get handed each element in the array which we can use. We use it like this (non arrow function example below):
functionsArray.forEach(element => {
element();
});
In a ForEach you can rename element in the above to be whatever you want. Renaming it, and not using arrow functions could look like this:
functionsArray.forEach(
function(funFunctionPassedIn) {
funFunctionPassedIn();
}
);
What about Map?
We shouldn't use Map in this case, since map builds a new array, and using map when we aren't using the returned array is an anti-pattern (bad practice).
We shouldn't be using map if we are not using the array it returns, and/or
we are not returning a value from the callback. Source
I know I am late to the party but here is my opinion
let new_array = [
(data)=>{console.log(data)},
(data)=>{console.log(data+1)},
(data)=>{console.log(data+2)}
]
new_array[0]
you got some top answers above. This is just another version of that.
var dictFun = {
FunOne: function(string) {
console.log("first function");
},
FuncTwo: function(string) {
console.log("second function");
},
FuncThree: function(string) {
console.log("third function");
}
}
/* PlanetGreeter */
class PlanetGreeter {
hello : { () : void; } [] = [];
planet_1 : string = "World";
planet_2 : string = "Mars";
planet_3 : string = "Venus";
planet_4 : string = "Uranus";
planet_5 : string = "Pluto";
constructor() {
this.hello.push( () => { this.greet(this.planet_1); } );
this.hello.push( () => { this.greet(this.planet_2); } );
this.hello.push( () => { this.greet(this.planet_3); } );
this.hello.push( () => { this.greet(this.planet_4); } );
this.hello.push( () => { this.greet(this.planet_5); } );
}
greet(a: string) : void { alert("Hello " + a); }
greetRandomPlanet() : void {
this.hello [ Math.floor( 5 * Math.random() ) ] ();
}
}
new PlanetGreeter().greetRandomPlanet();

How can I extend Array.prototype.push()?

I'm trying to extend the Array.push method so that using push will trigger a callback method and then perform the normal array function.
I'm not quite sure how to do this, but here's some code I've been playing with unsuccessfully.
arr = [];
arr.push = function(data){
//callback method goes here
this = Array.push(data);
return this.length;
}
arr.push('test');
Since push allows more than one element to be pushed, I use the arguments variable below to let the real push method have all arguments.
This solution only affects the arr variable:
arr.push = function () {
//Do what you want here...
return Array.prototype.push.apply(this, arguments);
}
This solution affects all arrays. I do not recommend that you do that.
Array.prototype.push = (function() {
var original = Array.prototype.push;
return function() {
//Do what you want here.
return original.apply(this, arguments);
};
})();
First you need subclass Array:
ES6 (https://kangax.github.io/compat-table/es6/):
class SortedArray extends Array {
constructor(...args) {
super(...args);
}
push() {
return super.push(arguments);
}
}
ES5 (proto is almost deprecated, but it is the only solution for now):
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);
};
Array.prototype.push was introduced in JavaScript 1.2. It is really as simple as this:
Array.prototype.push = function() {
for( var i = 0, l = arguments.length; i < l; i++ ) this[this.length] = arguments[i];
return this.length;
};
You could always add something in the front of that.
You could do it this way:
arr = []
arr.push = function(data) {
alert(data); //callback
return Array.prototype.push.call(this, data);
}
If you're in a situation without call, you could also go for this solution:
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;
}
While I'm telling you how to do it, you might be better served with using a different method that performs the callback and then just calls push on the array rather than overriding push. You may end up with some unexpected side effects. For instance, push appears to be varadic (takes a variable number of arguments, like printf), and using the above would break that.
You'd need to do mess with _Arguments() and _ArgumentsLength() to properly override this function. I highly suggest against this route.
Or you could use "arguments", and that'd work too. I still advise against taking this route though.
There's another, more native method to achieve this: Proxy
const target = [];
const handler = {
set: function(array, index, value) {
// Call callback function here
// The default behavior to store the value
array[index] = value;
// Indicate success
return true;
}
};
const proxyArray = new Proxy(target, handler);
I wanted to call a function after the object has been pushed to the array, so I did the following:
myArray.push = function() {
Array.prototype.push.apply(this, arguments);
myFunction();
return myArray.length;
};
function myFunction() {
for (var i = 0; i < myArray.length; i++) {
//doSomething;
}
}

Categories

Resources