Javascript从多个对象运行相同的函数

Javascript从多个对象运行相同的函数,javascript,Javascript,我有几个相同类型的对象,希望从每个对象运行相同的函数: 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"); 通常,我会这样做: dog.foo(); cat.fo

我有几个相同类型的对象,希望从每个对象运行相同的函数:

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");
通常,我会这样做:

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

但是,如果我有,比如说,一百个这样的方法,这不是一个非常有效的方法。有没有一种方法可以用几行代码从每只动物身上运行foo()。排序多个对象的最有效方法通常是数组。因此,您创建了一个包含所有动物的数组,并对每个动物调用foo。数组可以让您完全做到这一点,在代码中只调用函数一次,但在所有对象上都可以调用

在这里,您必须考虑是否在任何时候都可能存在没有foo()函数的动物。如果不是,请保持原样,如果是,则调用不同的函数或忽略特定的动物,具体取决于具体情况:

创建对象:

let animalArray = []
animalArray.push(new Animal("cat"))
animalArray.push(new Animal("dog"))
animalArray.push(new Animal("bird"))
animalArray.push(new Animal("hippo"))
animalArray.forEach(animal => animal.foo())
animals.forEach(animal => {
   if(animal.foo){
       animal.foo()
   }else{
       //call other function or ignore and do nothing
       animal.bar()
   }
})
对每个对象调用foo():

let animalArray = []
animalArray.push(new Animal("cat"))
animalArray.push(new Animal("dog"))
animalArray.push(new Animal("bird"))
animalArray.push(new Animal("hippo"))
animalArray.forEach(animal => animal.foo())
animals.forEach(animal => {
   if(animal.foo){
       animal.foo()
   }else{
       //call other function or ignore and do nothing
       animal.bar()
   }
})
ES5:

animalArray.forEach(function(animal){
   animal.foo() 
})
如果动物可能没有foo():

let animalArray = []
animalArray.push(new Animal("cat"))
animalArray.push(new Animal("dog"))
animalArray.push(new Animal("bird"))
animalArray.push(new Animal("hippo"))
animalArray.forEach(animal => animal.foo())
animals.forEach(animal => {
   if(animal.foo){
       animal.foo()
   }else{
       //call other function or ignore and do nothing
       animal.bar()
   }
})

首先,约定是将构造函数的大小写为大写

function Animal(name){
    this.name = name
    function foo(){
        console.log(this.name);
    }
}
我这样做是为了能够使用
animal
作为
reduce
中的变量而不发生冲突(也许我可以使用
name
,但我认为上面关于构造函数命名约定的一点是值得的)

然后,为了尽可能提高效率,因为你提高了效率,你大概是指代码行,把你所有的动物名字放在前面的一个数组中。然后使用
reduce
创建一个对象,该对象包含所有动物名称作为键和值作为
animal
实例。最后,我们可以通过调用
animalNames
上的
forEach
,按插入顺序循环
Animal
实例;animalObjects中的animal对象的
循环不保证按插入顺序返回对象

var animalNames = ['dog','cat','bird'];
var animalObjects = animalNames.reduce(function(result, animal), {
    result[animal] = new Animal(animal);
}, {});
animalNames.forEach(function(animal) {animalObjects[animal].foo()});
相比之下,公认的答案并不具有可伸缩性,当你添加动物时,你需要添加一个额外的呼叫来推动。使用我的示例,您需要做的就是向
animalNames
数组文本添加条目:

var animalNames = ['dog','cat','bird','squirrel','skunk','opposum']; //etc.
上面提到的另一个好处是,这些
动物名可以首先来自JSON

,如果您希望“foo”成为一个类方法,您需要将其绑定到这个类方法,或者更清晰地使用类定义。这是一种更实用的方法:

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());

@hippo_o__________________________________________________________,我更多的是指当你储存多个物体而不仅仅是动物的时候。所以如果你推新的动物()和新的外星人(),外星人没有foo()。但是,是的,你是正确的,如果它是唯一的动物,你不必考虑检查。