Confusion with Slice/Splice

Confusion with Slice/Splice
0.0 0

#1

I’m a tad bit confused as to why the following code is not passing any of the tests as it is running in the development console with no problems. I understand that the code is not fully fleshed out and correct in that arr2 is still being modified due to the use of splice, however the rest of the code checks out.

It’s my understanding we can use slice all day long without it modifying the original array. The problem arises when using splice. Mdn points to modifying Array.prototype, yet I’m wondering if there is an alternative. Any help would be very much appreciated!

Your code so far


function frankenSplice(arr1, arr2, n) {
var newArr = arr1.reverse();

for(i = 0; i < arr1.length; i++){
    arr2.splice(n, 0, arr1[i]);
}
return arr2;
}
frankenSplice([1, 2, 3], [4, 5, 6], 1);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-algorithm-scripting/slice-and-splice


#2

Look over your for loop and carefully look at your result window. It says “assignment to undeclared variable i”.


#3

In addition to what @thisiswhale pointed out, there is another use for Array.prototype.slice() that is mentioned in the MDN Web Docs:

The slice() method returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included)

This is commonly used to make a copy of an array primitive values before mutating operations, so that the original array can be preserved:

let arr = [0, 2, 3];
let result = arr.slice();

result.splice(1, 0, 1);

arr; // [0, 2, 3]
result; // [0, 1, 2, 3]

I hope that helps. :smile:


#4

Thanks for the help!

Interesting that in this instance it was required to strictly define i using the var keyword. Would this be due to strict mode? I’m still a little baffled why this would run without error in the developers console yet generate errors in FCC.


#5

The default in a browser’s console is indeed non-strict (at least for Firefox and Chrome it is)—you can verify this by:

for (i = 0; i < 10; i++) {
  console.log(i);
} 

console.log(i); // 10
console.log(window.i); // 10
'use strict';

for (j = 0; j < 10; j++) {
  console.log(j);
} 

// ReferenceError, strict mode does not allow variables to be created in the global scope
{
  'use strict';

  for (k = 0; k < 10; k++) {
    console.log(k);
  } 

  // This works because it's scoped away from global
}

I personally don’t think it’s a good idea to rely on that implicit declaration of the counter in the for loop, simply because the intent is not clear (and if you are really sloppy with your variables you could even end up overwriting it and produce unexpected behaviour).

Also, the default (if I’m not mistaken) is var—there are many situations where you would want to take advantage of the block-scoped declaration let (in the case of for loops, the variable is redeclared and scoped to each loop), so there is really no reason to leave it out.


#6

Thanks @honmanyau !

I agree that it’s probably better to strictly declare in order to avoid any ambiguity . My understanding of strict mode was fuzzy at best, however this definitely cleared up some mistaken assumptions I had. Thanks again!