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