Spread Operator Test - Teaching the Wrong Lesson

Tell us what’s happening:
To start with, let me just state that the ES6 tutorials are absolutely terrible, and I have learned absolutely nothing from them. I know this statement has been echoed time and time again on these forums, but I just want to be sure my voice is added to the choir. Whoever wrote the ES6 curriculum needs to take a very detailed analysis of their abilities as a teacher and truly determine if this is an area they believe they are adept in.

Now, for this question. There is nothing in the tutorial that teaches how to duplicate an array. Information is giving about the spread operator being used for math methods, and explicitly states I cannot do something like:

let array2 = ...arr1;

Great, now do you mind telling me what argument does work for copying an array without just pointing to the original, so that I can change arr2 without changing arr1? Because nothing in your lesson teaches me what that syntax might look like.

Oh, it gets better. Let’s check out the help page for spread operator. Wait a second, it’s just more examples of how to use math methods to manipulate an array using the spread operator as an argument? Not a single example of how to assign an array the value of another array? The actual test in the lesson?

Terrific. So, now, for the 6th or 7th lesson in a row, I will be navigating to a different tutorial site to learn what this lesson is actually asking me to do. I have high hopes for fCC 7.0 fixing the JavaScript lessons and I hope that whoever writes the project will look through the hundreds of posts on these forums about how poorly written the ES6 section is.

Hilarious Edit: One last thing, the first google result is this website explicitly stating why using spread to copy an array is wrong. So not only does this lesson not teach you the correct thing, it actually teaches you poor syntax. God save the soul of the person who wrote this section.

Your code so far


const arr1 = ['JAN', 'FEB', 'MAR', 'APR', 'MAY'];
let arr2;
(function() {
  "use strict";
  arr2 = ; // change this line
})();
console.log(arr2);

Your browser information:

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

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/use-the-spread-operator-to-evaluate-arrays-in-place

The author of the article say

It works, but I don’t like it for two reasons

There is no reason for which it shouldn’t be in the curriculum.

This doesn’t work because the spread operator makes ...arr1 the equivalent of a list of elements separated by commas, so not an array. What’s inside an array?

The video explain it, if you want the solution

The solution is simple. Wrong, but simple. The solution to the test case is not the problem here. The problem is the test case itself, which is ridiculous compared to the dozens of math methods you could run on this array to assign as a test case instead. The usage of spread is obviously meant for use cases such as math, so why not write a test that mimics this? Why write a test that is a poor version of a method that already exists for copying arrays?

Here’s how the test reads in plain English:

"Hey guys, here’s a pretty cool ES6 command that is an improved version of an ES5 command. See how this makes running math.method(…arr1) so much cleaner? Pretty cool!

One note, we can’t use spread for assign an array to another array directly.

Now, let’s go ahead and use spread to assign an array to another array directly. Go ahead!"

Here’s how the test would read if it was even remotely written well:

"Hey guys, here’s a cool ES6 command… yada yada yada.

One note: This isn’t meant to copy arrays, as “this method” and “this method” already exist for doing that! Isn’t that cool?

Now, let’s use a math method on the array in this test to make something happen. Remember to use a spread!"

I agree with you on the ES6 section, and on the poor wording, but using the spread operator to copy arrays is by far and away the most common use case, please don’t assume single internet person’s opinion on why they don’t like some syntax translates to actual usage.

Are we just ignoring the explicit reasons for why using spread is incorrect compared to methods like “from” that were explicitly created to do what spread is doing implicitly?

  1. It’s less explicit than using something like array.slice() or Array.from(sandwiches) . Both were made specifically to copy or create arrays, and the latter in particular tells you exactly what it’s doing in the name.
  2. Array.slice() has exceptional backwards compatibility, and Array.from() is polyfillable. The spread operator only works in the latest browsers and can’t be polyfilled.

It’s not incorrect. It does the same as both of those and is just as explicit, and is used all over in every codebase I’ve worked on for the last few years.

The spread operator only works in the latest browsers and can’t be polyfilled.

In practice this is rarely an issue, I’ve never worked on any production code that doesn’t use a build system and although there will be places that do not use build systems for JS, they are not terribly common. All modern browsers are evergreen, and build tools exist and are used as standard in almost every software dev environment.

So now we’re saying that any two things that do the same thing in production are equally correct? We are safe to ignore backwards compatibility, best practices, readability, and explicit instruction? That’s pretty sweet! I’ve only ever learned the exact opposite of these statements in every programming course I have ever attended, so I appreciate the info.

I’m pumped to start writing code such as:

const array1 = ['test1', 'test2', 'test3', 'test4'];
console.log(array1[0]);
console.log(array1[1]);
console.log(array1[2]);
console.log(array1[3]);

instead of using a for loop. I’m not even sure why they made a method such as array1.forEach() when I can just manually print out lines of code.

Edit: I get your point, I’m just pointing out how pointless your point is. If we’re going to start saying that “all code is equally good if it does what you want it to do” then why do best practices, or backwards compatibility exist at all?

Don’t be daft, there is no way on earth that an extremely useful syntax addition to JS is “bad practice”. Common usecases:

[...someArray] // copy array
[x, y, z, ...someArray] // concat values into new copy of array
[...someArray1, ...someArray2] // concat arrays

[..."somestring"] // break string into array of characters
[...new Set(...someArray)] // put array into set and then copy set to array (uniqueness)
[...new Map([[1, "foo"], [2, "bar"]])] // map -> array of k:v pairs
[...document.querySelectorAll('.someclass')] // nodelist -> array
// spread function arguments ("rest parameters")
function add(...args) {
  return args.reduce((a, b) => a + b, 0);
}
Math.min(...arrayOfVals) // find min without using apply
//etc etc

Much better! This answer is far and away the best example for what this lesson could or should be teaching. I appreciate you providing examples rather than just stating “some internet guy might have a bad opinion because I don’t like it.”

Edit: Look at that! Your reply taught me at least 7 more things than this lesson taught me. Much appreciated, again.

As long as we’re picking on the ES6 curriculum, I’d like to say that in the future curriculum, there shouldn’t even be an ES6 section. ES6 is also known as ES2015, i.e. a version that’s been official for four years now. Everything supports it. It’s not some esoteric extension to Javascript, it is javascript. Arrow notation should be covered immediately after anonymous function syntax. Spread operator after arrays. Class notation after the old-school notation (aside: I do however like how FCC covers OOP from first principles with functins and Object.create).

At the very least, var needs to be tossed into the legacy bin, with let and const coming first.

2 Likes