Constructor function for persons with hobbies
Performance

Strings are immutable, so using accumulator += stuffToAppend in a loop can traditionally impact performance. The problem is that we're creating a new string every iteration, leading to quadratic time complexity for an operation that should be linear. It turns out that modern browsers optimize this heavily using an internal array to represent string parts and make it quite fast over using an explicit array, so this post is focused on style rather than performance.

Design

On first thought, reduce seems like the right function from a semantic standpoint since we want to boil the array of interests down to one string. However, since avoiding string concatenation requires an intermediate array in reduce, we might as well just skip the intermediate array and use map and join. It's pretty common that reduce can be replaced with map or filter, which are more specific and succinct.

Switch statements are also generally not used much in JS (but often used in C...). You can replace many switch statements in JS with an object (particularly if you're choosing between a number of similar functions), or at least an if statement. Either way, the nature of the commas and "and" in this example makes it a bit awkward, so there doesn't seem to be any clear-cut win.

Additionally, this routine of "prettifying" a list is generic and can be moved to a separate function to keep Person clean.

As an aside, instead of switching between "interests", "hobbies" and "bio", it seems best to pick one term and stick with it throughout. 

Here's my attempt. This might seem a bit abstract, but it's typical in JS to avoid conditional/switch stuff as much as it is to avoid loops (which is the idea with reduce). If you prefer a more traditional approach, replace the joins array and indexing with an if statement and I'd still endorse it.



const prettyList = (a, sep=", ", endSep=[" and ", "."]) =&gt; 
  a.map((e, i) =&gt; e + (endSep[endSep.length-a.length+i] || sep)).join("")
;

const Person = function (interests=[]) {
  this.interests = interests;
  this.interestsSentence = prettyList(interests);

  this.interestsStr = () =&gt; 
    "This person's interests are: " + this.interestsSentence
  ;
};

const interests = ["foo", "bar", "baz", "quux"];

for (let i = 1; i &lt;= 4; i++) {
  console.log(new Person(interests.slice(0, i)).interestsStr());
}




Now the function is reusable and we can change its behavior without much effort at all:



const prettyList = (a, sep=", ", endSep=[" and ", "."]) =&gt; 
  a.map((e, i) =&gt; e + (endSep[endSep.length-a.length+i] || sep)).join("")
;

const activities = ["biking", "running", "walking", "skipping", "driving"];
console.log("I love", prettyList(activities, "; ", [", sometimes ", " but not ", "!"]));
console.log("I love", prettyList(activities, " and ", [" while ", " :-o"]));