Hacker News new | past | comments | ask | show | jobs | submit login

Some of them are stretched examples, others comes from other languages/constraints (floating point, octal, ...), but some other are legitimately weird and error prone:

[1, 2, 3] + [4, 5, 6] // -> "1,2,34,5,6"

[,,,].length // -> 3




The first is only weird if you expect the + operator to perform an operation on arrays. It doesn't, so each array becomes a string and those two strings are concatenated.

The second is only weird in that you are constructing an array with implicit undefined values, which is exactly what I would expect to happen if my linter didn't complain about the syntax and I had to guess what might be happening.


> The first is only weird if you expect the + operator to perform an operation on arrays.

Like GP said, comes from other languages. That line can be copy/pasted into python and it performs concatenation.


Both of these examples are well-known (and not unexpected) behaviours. I assume you already know why it behaves like that. If not, I can explain it.

> [1, 2, 3] + [4, 5, 6] // -> "1,2,34,5,6"

What would you expect instead?

> [,,,].length // -> 3

Is there any use case where you would want to deal with sparse arrays?


[1,2,3] + [4,5,6]

An addition operation over two numerical vectors of length 3.

I would expect the result to match its inputs and provide a numerical vector of length 3.

Thus: [5, 7, 9]


The issue there is that arrays aren't first class types in JS, they're just objects with numeric property names.

So if applying an operator to arrays spread the operation across all the elements that way, it would imply that the same should happen generally for all object properties, with whatever weird implications that would entail.

    a.foo = 1
    b.foo = 'there'
    a + b // { foo: '1there' } ?


What language has this behavior by default?


Fortran :)


> [1, 2, 3] + [4, 5, 6] // -> "1,2,34,5,6"

> What would you expect instead?

If I let my first instinct speak:

[1,2,3,4,5,6]

And then if I think a little more, then maybe:

[5,7,9] //with obvious caveats

In no way do I expect what GP actually provided.


I understand where you are coming from. But the addition operator simply does not have any special handling of arrays. The specification [1] clearly defines what it should be used for: "The addition operator either performs string concatenation or numeric addition." As JavaScript is weakly typed, it is the programmer's responsibility to use proper value types with these operators. That limitation (or advantage?) is also well-known and applies to all weakly-typed languages.

[1] https://tc39.es/ecma262/multipage/ecmascript-language-expres...


It seems that by "expected", you mean "expected, by anyone who read the spec" which I don't think is a fair use of that word. Obviously, most JS developers have not and will not read the spec.

I am very happy with JS and TS and I think the coercion rules are easily worked around with linter rules and policies, but they are definitely weird and I think the language would be better if it simply threw exceptions instead. But then, such an issue shoud not be surprising for a language that was designed in 10 days.


No, I meant "expected by anyone who learned the language". Knowing the addition operator including its limitations is quite basic. I'm not saying you need to be able to solve all this "JavaScript is weird" puzzles as they are mostly non-sense. But you definetely have to know what you can us `+` for.

If someone does not like the ECMAScript specification, that is fine. But at least use a proper unofficial documentation like MDN.


well I guess the question is then not just what would you expect instead but at what familiarity with the language should one be asking people what they expect of it?

If you ask experts it is because you want to get an actual correct answer, but if you ask neophytes it is because you want to get an answer that might be obvious even if not correct.


Perl would give you 9 for the equivalent expression of (1,2,3)+(4,5,6) :)


> Is there any use case where you would want to deal with sparse arrays?

Not really. Now explain why [,,,].map((e,i) => i) is [,,,] instead of [1,2,3] please ;)


(assuming you're really asking) It's because JS has a notion of array elements being "empty", and the map operation skips empty elements. Basically "empty" means the element has never had a value assigned to it, but its index is less than the array's length property.

    Array(4)               // [empty × 4]
    a=[]; a.length=4; a    // [empty × 4]
    Array(4).map(n => n)   // [empty × 4]
    [,,1,,].map(n => n)    // [empty × 2, 1, empty]
My go-to way of avoiding this annoyance is "Array.from(Array(N))":

    Array.from(Array(4)).map((n,i) => i)  // [0, 1, 2, 3]
Alternately there's a recent "fill" method, that assigns all elements (including empty ones) to a given value:

    Array(4).fill(1)      // [1, 1, 1, 1]


> [,,,].length // -> 3

I don't think this is too weird if you think about it. JS allows trailing commas, so the last one is ignored. Effectively this is `[ undefined, undefined, undefined, ]`. A syntax error would have made sense here, but the length of three is a result of the usual syntax rules, not a particular strange quirk of JS.


Sorry to be pedantic, but `[,,,]` creates holes instead of undefined. They are different, because for example `[,,,].forEach(() => console.info(1))` doesn't do anything, but `[undefined,undefined,undefined,].forEach(() => console.info(1))` prints three "1"'s.


I could also make a php is weird page and say:

"WAT $a .= "World!"; ?"


Yes. You could.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: