0

Why does it happen that the below code throws the error Uncaught ReferenceError: Cannot access 'arr' before initialization

function swap(str,a,b){
    let arr = str.split("")
    [arr[a],arr[b]] = [arr[b],arr[a]]
    return arr.join("")
}
swap("abcde",2,4) // throws error "Uncaught ReferenceError: Cannot access 'arr' before initialization"

But as soon as I insert any dummy statement between line 2 and 3, surprisingly code starts to work

function swap(str,a,b){
    let arr = str.split("")
    23456; // this could be anything like a variable declaration, or any valid javascript statement
    [arr[a],arr[b]] = [arr[b],arr[a]]
    return arr.join("")
}
swap("abcde",2,4) // returns "abedc" as expected

I am surprised to see why does this even work now ? It should have given error in both the cases, or should have worked in both cases. I'm sure that in the 1st case, split is not finishing it's work till the time line 3 is executed and in 2nd case, it is getting enough time because of 1 extra statement in between. But I would still love to get a clear explanation as to why it is behaving like this. I'm not sure if this is same for all browsers, but I've tried it on Chrome and Safari on mac, and both of them gave same error.

2 Answers2

3

The semicolon is making the difference. JavaScript thinks you want to access the result of str.split("")[arr[a],arr[b]] like an array. This is why JavaScript autoformatters will insert a semicolon at the beginning of the next line like this:

function swap(str,a,b){
    let arr = str.split("")
    ;[arr[a],arr[b]] = [arr[b],arr[a]]  // <--- semicolon in front of this line
    return arr.join("")
}
Tobias S.
  • 21,159
  • 4
  • 27
  • 45
  • I've tried it in browser console No autoformatter is used here But your explaination however seems to be correct – Ashutosh Singhai Dec 25 '21 at 03:55
  • If you would use a formatter, than it would insert this semicolon for you. This is actually how this is supposed to be written (even though it looks wrong on first sight) – Tobias S. Dec 25 '21 at 03:56
  • That's why I prefer using semicolons. – sujeet Dec 25 '21 at 03:57
  • Using semicolon in front of statement is still something familiar What is not familiar is, the interpreter not considering `arr = str.split("")` as a complete statement and looking for tokens in next line. We all know that Javascript can work well even without semicolons, so this is a bit surprising to me – Ashutosh Singhai Dec 25 '21 at 04:00
1

I think your syntax is off a bit split will return an array and trailing it with brackets is translated as if you are trying to access an element of the array I believe you are missing the semi colon only

let arr = str.split("")[arr[a],arr[b]] = [arr[b],arr[a]]

function swap(str,a,b){
    let arr = str.split("");
    [arr[a],arr[b]] = [arr[b],arr[a]]
    return arr.join("")
}

console.log(swap('some tpyo', 6, 7))
Neveen Atik
  • 141
  • 4