0

The internet, including Stackoverflow states that Javascript does not accept type specific parameters (one such article here). However, why does ES6 accept an array literal as the parameter for a function and when I pass a primitive it throws a Type Error?

I am having a hard time wrapping my head around what Javascript is doing in the background. I thought Javascript typically takes a variable name as the parameter in a function declaration and allocates memory for that name and assigns the value of whatever argument I pass to the parameter. I am not sure if this is exclusively in the Arguments Object or elsewhere also. In the example below, however, I do not have a variable name for the array literal. I just don't know how Javascript is interpreting this parameter.

In the code below I define a function using an array literal as the parameter and when I try to pass a primitive as an argument it produces a TypeError.

 function box([width,height]) {
   return `I have a box that is ${width} x ${height}`;
 }

console.log(box([6,6])); //NO error

console.log(box(6)); //produces error, Webstorm says, "TypeError: 
undefined is not a function"
Jacki
  • 1
  • You are not sending the function a height via the expected array element. – Jeff Matthews Feb 01 '18 at 22:48
  • 3
    It's not an array literal as the parameter, it's a [destructuring assignment](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment), which basically says "this function accepts an array, and it takes the first element and assigns it to width, and the second assigned to height" If you fail to pass in array that can't work and you get an error. – James Feb 01 '18 at 22:50
  • as @James said, except it's not limited to Arrays but you can pass every [iterable value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator) to the function, to be destructured. So `box("12")` also works, just not as expected ;) – Thomas Feb 01 '18 at 22:58
  • You can check what is going on in [Babel REPL](https://babeljs.io/repl/) for example Try to put your code in it – Andrii Muzalevskyi Feb 01 '18 at 23:00
  • @James: I am new to overstackflow so I don't know if I should respond here or not. OR, how to give you feedback because your answer was helpful. My interpretation of what you said is that basically I should think of "destructuring assignment" as an expression rather than a datatype. Similar to a mathematical expression I can pass it as a parameter to the function and when that function is called it will "return" a value. It is the value that is used as the parameter and not the expression itself? – Jacki Feb 01 '18 at 23:27
  • Right it's like an expression. You can think of the width and height labels as local variables that receive the values corresponding to their positions from the structure that was passed in (if possible). – James Feb 02 '18 at 01:15

1 Answers1

0

This behavior is documented in the ES6 specification Destructuring assignments. In the Runtime Semantics section, the definition of the array destructuring assignment is

ArrayAssignmentPattern : [ ]

Let iterator be GetIterator(value).
ReturnIfAbrupt(iterator).
Return IteratorClose(iterator, NormalCompletion(empty)).

It's pretty interesting to dig into it. The array destructuring assignment (so it is an assignment) expects an iterable, that is: an object for which obj[Symbol.iterator] is defined as a function returning an iterator. Try testing this in a console of a browser that supports it (tests done on Firefox 57). In fact when you do:

let [a,b] = 5 //smaller reproduction of the error

you will get TypeError: 5 is not iterable. Contrast with below:

let number = new Number(5);
number[Symbol.iterator] = function*() {
  yield 5;
}
let [f,g] = number; // works, f === 5, g === undefined

Probably under the hood JS destructuring maps the named array indexes to a slot which represents the next iteration of the iterator. Numbers do not have a built-in [Symbol.iterator] property, hence the error

webketje
  • 10,376
  • 3
  • 25
  • 54
  • I don't see what your first paragraph about early errors has to do with the question? There are no syntax errors in the OPs code. – Bergi Feb 02 '18 at 01:51