3

I have several objects of the same type, and want to run the same function from each of them:

function animal(name){
    this.name = name
    function foo(){
        console.log(this.name);
    }
}

var dog = new animal("dog");
var cat = new animal("cat");
var bird = new animal("bird");

Usually, I would just do this:

dog.foo();
cat.foo();
bird.foo();

But this isn't a very efficient way of doing it if I have, say, a hundred of these. Is there a way to run foo() from every animal with just a few lines?

0

4 Answers 4

5

Well, to do it efficiently you must have your objects organised efficiently. The most efficient way to order multiple objects is usually an array. So you create an array with all your animals and call foo on each of them. Arrays will let you do exactly that, call the function only once in code but have it happen on all objects.

Here you have to think about if at any time there might be an animal without the foo() function. If not, just leave it as is, if yes then you call a different function or just ignore that specific animal, depending on the case:

Creating the objects:

let animalArray = []
animalArray.push(new Animal("cat"))
animalArray.push(new Animal("dog"))
animalArray.push(new Animal("bird"))
animalArray.push(new Animal("hippo"))

Calling foo() on each object:

animalArray.forEach(animal => animal.foo())

ES5:

animalArray.forEach(function(animal){
   animal.foo() 
})

If an animal might not have foo():

animals.forEach(animal => {
   if(animal.foo){
       animal.foo()
   }else{
       //call other function or ignore and do nothing
       animal.bar()
   }
})
Sign up to request clarification or add additional context in comments.

2 Comments

Why does he have to think about Animal instances without the foo method: it's right there in the constructor function
Oh that might be confusing youre right, I was more refering to when you store multiple objects and not strictly just animals. So in case you push new Animal() and new Alien() and aliens dont have foo(). But yes youre right if its only animals you shouldnt have to consider checking
0

First if you want "foo" to be a classMethod you need to bind it to this, or clearer way, use a class definition. And this is a more functional approach:

class Animal {
  constructor(name) {
    this.name = name;
  }
  woof(){
    console.log(this.name, 'is woofing!');
  }
}

var animalNames = ['dog', 'cat', 'bird'];

var animals = animalNames.map((name) => new Animal(name));

animals.map((animal) => animal.woof());

Comments

0

First of all, the convention is to upper case your constructor function

function Animal(name){
    this.name = name
    function foo(){
        console.log(this.name);
    }
}

I specifically did this to be able to use animal as a variable inside reduce without a collision (maybe I could have used name, but I thought the above point regarding naming convention for a constructor function was worth it).

Then, to make this as efficient as possible, since you bring up efficiency, by which you presumably mean lines of code, put all your animal names into an array up front. Then create an object consisting of all the animal names as keys and values as Animal instances, by using reduce. Finally, we can loop over the Animal instances in insertion order by calling forEach on animalNames; a for animal in animalObjects loop is not guaranteed to return the objects in insertion order.

var animalNames = ['dog','cat','bird'];
var animalObjects = animalNames.reduce(function(result, animal), {
    result[animal] = new Animal(animal);
}, {});
animalNames.forEach(function(animal) {animalObjects[animal].foo()});

The accepted answer in comparison doesn't scale, as you add animals you need to add an additional call to push. Using my example above all you have to do is add entries to the animalNames array literal:

var animalNames = ['dog','cat','bird','squirrel','skunk','opposum']; //etc.

A further benefit of the above is that these animalNames could come from JSON

Comments

-3

you can create an array, and then loop through the array, calling the function

1 Comment

@hippo_o_matic I think you will find the other answers with code examples to be more helpful

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.