Functional Programming - Understand the Hazards of Using Imperative Code

Why is this line correct? const tabsAfterIndex = this.tabs.splice(index + 1)

I thought splice took 3 parameters. This only has 1 parameter.

// tabs is an array of titles of each site open within the window
const Window = function(tabs) {
  this.tabs = tabs; // We keep a record of the array inside the object
};

// When you join two windows into one window
Window.prototype.join = function(otherWindow) {
  this.tabs = this.tabs.concat(otherWindow.tabs);
  return this;
};

// When you open a new tab at the end
Window.prototype.tabOpen = function(tab) {
  this.tabs.push('new tab'); // Let's open a new tab for now
  return this;
};

// When you close a tab
Window.prototype.tabClose = function(index) {

  // Only change code below this line

  const tabsBeforeIndex = this.tabs.slice(0, index); // Get the tabs before the tab
  const tabsAfterIndex = this.tabs.splice(index + 1); // Get the tabs after the tab

  this.tabs = tabsBeforeIndex.concat(tabsAfterIndex); // Join them together

  // Only change code above this line

  return this;
 };

// Let's create three browser windows
const workWindow = new Window(['GMail', 'Inbox', 'Work mail', 'Docs', 'freeCodeCamp']); // Your mailbox, drive, and other work sites
const socialWindow = new Window(['FB', 'Gitter', 'Reddit', 'Twitter', 'Medium']); // Social sites
const videoWindow = new Window(['Netflix', 'YouTube', 'Vimeo', 'Vine']); // Entertainment sites

// Now perform the tab opening, closing, and other operations
const finalTabs = socialWindow
  .tabOpen() // Open a new tab for cat memes
  .join(videoWindow.tabClose(2)) // Close third tab in video window, and join
  .join(workWindow.tabClose(1).tabOpen());
console.log(finalTabs.tabs);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0

Challenge: Functional Programming - Understand the Hazards of Using Imperative Code

Link to the challenge:

MDN Array.prototype.splice()

It can take anywhere from 0 parameters to as many as you can throw at it.

A better way to visualize how splice can be used is on the MDN docs and looks like this:

splice(start)
splice(start, deleteCount)
splice(start, deleteCount, item1)
splice(start, deleteCount, item1, item2, itemN)

see: Array.prototype.splice() - JavaScript | MDN

Even the first paramater, start is optional as it defaults to 0 if omitted.

Thanks for that link. Sounds like it is saying that that syntax is only valid when adding something onto the end of the array.

AND

You want to delete or replace everything in the array with the insert data.
Which would also explain why push() would not be valid here. Correct?

Thanks for your help!

1 Like

Close!

When you only supply the first argument to the splice function, you’re basically saying, remove everything from start to the end of the array and return it. It also mutates the original array

So for example:

let arr = [0, 1, 2, 3]

console.log(arr.splice(2)) // [2, 3]

console.log(arr) // [0, 1]

So in the example you shared:

const tabsBeforeIndex = this.tabs.slice(0, index); // Returns the tabs before the tab (but does not mutate)
const tabsAfterIndex = this.tabs.splice(index + 1); // Returns the tabs after the tab (but mutates `tabs`)

It’s valid to call push on the result, however because on the line where the two arrays are joined together, you’re expecting the result to be the new array, push won’t work.

this.tabs = tabsBeforeIndex.concat(tabsAfterIndex); // Returns the merged array

this.tabs = tabsBeforeIndex.push(tabsAfterIndex); // Returns the length of the merged array (not what you want here)
1 Like