Context of Array() in this function

Viewed 116
  it("should know properties that are functions act like methods", function() {
    var meglomaniac = { 
      mastermind : "Brain", 
      henchman: "Pinky",
      battleCry: function(noOfBrains) {
        return "They are " + this.henchman + " and the" +
          Array(noOfBrains + 1).join(" " + this.mastermind);
      }
    };

    var battleCry = meglomaniac.battleCry(4);
    expect('They are Pinky and the Brain Brain Brain Brain').toMatch(battleCry);
  });

What is the definition of Array in this code (line 7)? I looked it up and it looks like it's an Array.of() command which generates an empty array of length n which in this case would be 5? So why does it end up with only 4 brain inputs assuming that is the correct assumption? Or is this array() doing something else?

2 Answers

battleCry(4) means that Array(noOfBrains + 1) will indeed have a length of 5:

[empty, empty empty, empty, empty]

But when you .join those 5 elements, you only insert something into the spaces between them, and there are only 4 spaces:

[empty, empty empty, empty, empty]
//     ^     ^      ^      ^

So, you end up with 4 occurrences of this.mastermind in the resulting string.

This code is quite confusing. I'd strongly prefer something like .repeat instead:

var meglomaniac = { 
  mastermind : " Brain", 
  henchman: "Pinky",
  battleCry: function(noOfBrains) {
    return `They are ${this.henchman} and the${this.mastermind.repeat(noOfBrains)}`
  }
};

var battleCry = meglomaniac.battleCry(4);
console.log(battleCry === 'They are Pinky and the Brain Brain Brain Brain');

Array is just the array constructor. It's not really anything special, it just creates an array which has a length of the parameter (when passed a number).

You can avoid having to manually add 1 to the number of elements in the Array to overcome the problem, by using Array.fill().

Array(4).fill("Brain").join(" ");   // have an array of 4 elements,
                                    // fill each vacant spot with "Brain"
                                    // and flatten it by separating elements
                                    // by a space
//Brain Brain Brain Brain

So your code can be simplified as:

Array(noOfBrains).fill(this.mastermind).join(" ");
Related