I would like to store function pointers in an Array and then execute all of them in a foreach loop.
var array = new Array();
array['foo'] = function() { doFoo(); };
array['bar'] = function() { doBar(); };
How do I iterate and execute all functions in array?
First, if you really want to use non-numeric property names, you don't need an array:
var obj = {};
obj["foo"] = function() { doFoo(); }
obj["bar"] = function() { doBar(); }
To iterate and call the functions:
for (var k in obj) {
obj[k]();
}
To be pedantic, it's usually considered a good idea to make sure you're not running into unexpected properties inherited from the prototype:
for (var k in obj) {
if (obj.hasOwnProperty(l))
obj[k]();
}
Related
I already have a solution, but I want to understand the why.
var returnObj = {};
//declare object
var copyObj = {};
for (var k in data.data) {
for (var i = 0; i < data.data[k].offerId.length; i++) {
if (obj.hasOwnProperty(data.data[k].offerId[i])) {
(function() {
var offerId = data.data[k].offerId[i];
var verticalId = k;
copyObj = obj[offerId];
//this does not work - overwrites similar object in array
if (returnObj[offerId] !== undefined) {
copyObj.value = 'something';
returnObj['copy'] = copyObj;
} else {
copyObj.value = 'something else';
returnObj[offerId] = copyObj;
}
})();
}
}
}
So my question is, what is going on with the scope and the variable reference that causes my attempt at creating a new slot in the array for an object that already exists, to overwrite the already existing object in the array? My copyObj.value will be the something at both returnObj['copy'] and returnObj[offerId].
I have a solution already, and that is to use angular.copy(), but I wanted to know why updating the copyObj would affect the previously stored value?
Is there any other way to copy the object (instead of using angular.copy())?
I'm trying to backwards engineer the array methods push, pull, shift, unshift, but I can't seem to figure out how to a) construct it b) call it. How could I do this? Here are the conditions:
returns an empty array object. this object should have the
following methods: push(val) adds val to the end of the array
pop() removes a value from the end and returns it unshift(val) adds
val to the beginning of the array shift() removes a value from the
beginning and returns it the goal of this problem is to reverse
engineer what array methods are actually doing and return an object
that has those methods
Here is what I initially thought it should look like.
function createArray() {
//CODE HERE
this.push = function Push(value){
if(index >= 0){
Mainarray[index++]=value;}
};
this.pop = function (){
if(index >= 0){
index--;
return Mainarray[index];
}
else{
// display message of Empty Array
console.log('Error: Item is not array');
}
};
this.unshift = function(){return ;};
}
You could use prototypes — like this:
function YourArray() {
this.arr = [];
this.index = 0;
}
YourArray.prototype.push = function( value ) {
this.arr[ this.index++ ] = value;
return this;
}
var arr = new YourArray();
arr.push('foo');
function NewArray() {
this.array = [];
}; /* Class */
NewArray.prototype.push = function(data) {
this.array.push(data);
} /* Method */
/* You should use prototypes, because all methods will became common, and if you are created methods like this.pop = function (){} then any instance will copy this functions */
var n = new NewArray();
n.push(2);
console.log(n);
Advantages of using prototype, vs defining methods straight in the constructor?
You can recreate the push method by assigning you array at position the length of the same array a value.
This is the prototype for the push:
Array.prototype.push = function(element) {
this[this.length] = element;
};
and this is for the pop method:
Array.prototype.pop = function() {
var key = this.stack.pop();
var prop = this.object[key];
delete this.object[key];
return prop;
};
You can make your own methods by changing the prototype names.
push to mypush or sthing
Example for your push function createArray:
this.push = function pushValue(value) {
this.arr[this.arr.length] = value;
};
I used native arrays methods as values assigned to keys in the returned object. The trick is to declare an array inside the object and use it as a reference. It should pass the checks you`re looking for.
function createArray() {
//CODE HERE
return {
arr: [],
push: function (val) {this.arr.push(val)},
pop: function() {return this.arr.pop()},
unshift: function (val) {return this.arr.unshift(val)},
shift: function() {return this.arr.shift()}
}
}
I'm curious how to go about implementing my own sort function on the Array object. Ignoring all the usual warnings/dangers about extending/overriding a built-in, consider this:
Array.prototype.sort = function() {
this = mySortFunction(this);
function mySortFunction(arr) { ... };
};
Inside the closure, this refers to the Array object [number, number2, number3, etc.]. How do I go about reassigning this to be the result of my internal sorting function? Is it possible?
Your solution seems a little redundant:
Array.prototype.sort = function() {
this = mySortFunction(this);
function mySortFunction(arr) {
arr = yetAnotherSortFunction(arr)
function yetAnotherSortFunction(arr2) {...}
// and so on...
};
};
If you really want to do it this way, why not reference your array directly in the first place:
Array.prototype.sort = function() {
// your implementation:
// for (var i = this.length, ...
// if (this[0] == ...
// this[i] = ...
// ...
};
I have a function that looks like this:
var tempFun = function() {
return 'something';
}
tempFun.priority = 100;
Now I'm pushing it to an array and binding another object to it in the process like this:
var funArray = [];
var newObj = {};
funArray.push( tempFun.bind(newObj) );
and after this, I would like to acces the function's property like this:
funArray[0].priority
but it returns undefined. Is there some way to preserve the property on the function while binding a new object to it?
No, but you could write a function to do this yourself;
Function.prototype.bindAndCopy = function () {
var ret = this.bind.apply(this, arguments);
for (var x in this) {
if (this.hasOwnProperty(x)) {
ret[x] = this[x];
}
}
return ret;
};
... which you could then use via;
var funArray = [];
var newObj = {};
funArray.push( tempFun.bindAndCopy(newObj) );
No. Bind returns a new function, which "wraps" around the original one. All you can do is copy the properties on this new function:
var boundFun = tempFun.bind(newObj)
boundFun.priority = tempFun.priority;
funArray.push( boundFun );
If you want the properties to be in sync (changes in one visible on the other) you can do:
Object.defineProperty(boundFun, 'priority', {
get : function () { return tempFun.priority; },
set : function (val) { tempFun.priority = val; }
});
From MDN:
The bind() method creates a new function that, when called, has its
this keyword set to the provided value, with a given sequence of
arguments preceding any provided when the new function is called.
Hence, .bind() won't be useful for what you're trying to achieve. Besides using jQuery mappers or rewriting your code to use .prototype, a solution that I can think of is:
var obj = {};
for (var i in tempFun) {
if (tempFun.hasOwnProperty(i)) obj[i] = tempFun[i];
}
In Google Apps JS. I would like to implement an array of objects, each with properties and methods. One of the properties needs to be an array of objects and I would like to be able to access this array by using methods in the parent array.
So far my best efforts is:
function myFunction () {
var teamNo = 3;
var allNames =["n1","n2","n3","n4"] ;
var createnames = function () {
var names = [];
for ( var j = 0; j <=3 ; j ++) {
(function (j) {
var localNames = ["local1-names"+j,"local2-names"+j];
names[j] = (function (player){
return {
namArr: localNames,
name: allNames[j],
addName: (function (player){
localNames.push(player);
}) (player),
team: teamNo
};
});
}) (j);
}
return names;
}
var myname = createnames();
var foo = myname[0]().namArr;
var foo1 = myname[1]().namArr;
myname[1]().addName("added");
var foo2 = myname[1]().namArr;
var foo3 = myname[2]().namArr;
var debug = true;
}
As soo as I add the code to implement the sub array I get a runtime error saying that addName does not exist.
You're invoking this immediately:
addName: (function (player) {
localNames.push(player);
})(player)
instead of assigning it:
addName: function (player) {
localNames.push(player);
}
Also, each names[] function takes a player, and so does the addPlayer() function, making the names[] parameter unreachable. If you're not going to pass anything to the names[] functions, then remove the parameter.
And I'd suggest using named functions instead of inlined IIFEs.