对象文字和对象构造函数在一个数组中的潜在问题?

时间:2018-02-24 07:21:45

标签: javascript class constructor polymorphism literals

我想深入理解JavaScript中的对象创建。一般来说,我理解创建方法之间的差异等。在这两种情况下,当我使用以下两种方式创建数组中的对象时,您能描述使用对象数组的差异和影响吗?

function Animal(name, species) {
  this.name = name,
  this.species = species
}

var animals = [
  {name: 'azor', species: 'dog'},
  {name: 'mruczek', species: 'cat'},
  {name: 'burek', species: 'dog'},
];

//Case 1
newAnimal = {name: 'motek', species: 'buterfly'}
animals.push(newAnimal);
console.log(animals);

console.log('---');

//Case 2
newAnimal = new Animal('bongo', 'elephant');
animals.push(newAnimal);
console.log(animals);

我问,因为如果我使用console它会显示

[ { name: 'azor', species: 'dog' },
  { name: 'mruczek', species: 'cat' },
  { name: 'burek', species: 'dog' },
  { name: 'motek', species: 'buterfly' } ]
---
[ { name: 'azor', species: 'dog' },
  { name: 'mruczek', species: 'cat' },
  { name: 'burek', species: 'dog' },
  { name: 'motek', species: 'buterfly' },
  Animal { name: 'bongo', species: 'elephant' } ]

问题

使用//Case 2中相同数组中的文字和构造函数创建对象是否有问题?

1 个答案:

答案 0 :(得分:1)

如果您希望所有对象真正成为instanceof Animal,则可以使用Object.setPrototypeOf()重新定义对象“prototype

class Animal {
  constructor (name, species) {
    this.name = name;
    this.species = species;
  }

  greet () {
    return `My name is ${this.name} and I am a ${this.species}`;
  }
}

var animals = [
  {name: 'azor', species: 'dog'},
  {name: 'mruczek', species: 'cat'},
  {name: 'burek', species: 'dog'},
];

animals.push({name: 'motek', species: 'buterfly'});
animals.push(new Animal('bongo', 'elephant'));

animals.forEach(animal => {
  Object.setPrototypeOf(animal, Animal.prototype)
});

console.log(`Are all the animals actually an Animal? ${
  animals.every(animal => animal instanceof Animal)
}`);
console.log(animals.map(animal => animal.greet()));

或者您可以使用一种多态来通过Function.prototype.call()来处理Animal之类的所有对象:

class Animal {
  constructor (name, species) {
    this.name = name;
    this.species = species;
  }

  greet () {
    return `My name is ${this.name} and I am a ${this.species}`;
  }
}

var animals = [
  {name: 'azor', species: 'dog'},
  {name: 'mruczek', species: 'cat'},
  {name: 'burek', species: 'dog'},
];

animals.push({name: 'motek', species: 'buterfly'});
animals.push(new Animal('bongo', 'elephant'));

// animals.forEach(animal => {
//   Object.setPrototypeOf(animal, Animal.prototype)
// });

console.log(`Are all the animals actually an Animal? ${
  animals.every(animal => animal instanceof Animal)
}`);
console.log(animals.map(animal => Animal.prototype.greet.call(animal)));

请注意,在这种情况下,它们仍然是最初定义的,但您可以调用prototype的{​​{1}}方法,并将每个实例作为调用上下文传递。

哦,Animal输出不同的原因是因为[Symbol.toStringTag]属性,你可以重载:

console.log()