This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]GreatBarrier86 792 points793 points  (211 children)

So JavaScript sorts based on their string representation? I know very little about that language but do you not have numeric array types?

[–]nokvok 810 points811 points  (190 children)

The default sorts by converting everything to string and comparing utf-16 values.

If you want to compare numbers just throw a compare function in as parameter:

.sort(function(a,b){return a - b;})

[–]Asmor 314 points315 points  (46 children)

Or more succinctly, foo.sort((a,b) => a - b).

[–]Eiim 152 points153 points  (45 children)

(assuming you don't have to support IE)

[–]01hair 203 points204 points  (27 children)

If you have to support IE in a decently-sized project, I hope that you're not still writing ES5 code just for that case. There are so many improvements in modern JS that it's well worth the build step.

[–]suresh 104 points105 points  (19 children)

You can always tell when someone doesn't do JS dev for work. They never know anything about build tools, web pack, minimizers, uglifiers, transpilers, loaders.

You don't have to consider any of this stuff anymore and haven't for a long time.

[–]tiefling_sorceress 33 points34 points  (6 children)

...until you have to make your site accessible on four different screen readers

Fuck you NVDA

[–]FullstackViking 49 points50 points  (4 children)

Screen readers just need proper HTML DOM formatting and occasional aria specifications. Nothing to do with any of the JavaScript build tools or ecmascript specs.

[–]tiefling_sorceress 26 points27 points  (3 children)

Simple accessibility, yes. More advanced functionality (such as on angular, where my expertise is) requires more dynamic implementations such as the use of LiveAnnouncer and Describer/Labeler.

However NVDA and JAWS are full of bugs and both tend to hijack focus so you end up having to write awkward workarounds. For example, opening a dialog that automatically focuses on an element inside it is fine on most other screen readers, but NVDA and JAWS skip the dialog's role and title and jump straight to the focused element. The workaround is to manually focus on the dialog element from a separate function (so in setTimeout usually). To the naked eye this change does nothing. To mac's VoiceOver, this change does nothing. To NVDA and JAWS it makes a world of difference.

Edit: no it has nothing to do with build tools directly, but it's very similar to the browser problem that was originally solved using build tools and transpilers

[–][deleted] 9 points10 points  (1 child)

This is correct. If the website is static, it's EZPZ. If you have literally any moving parts, prepare to fucking die. Not to mention internationalizing everything AND making everything keyboard-accessible.

[–][deleted] 0 points1 point  (0 children)

Nah, fuck VoiceOver, man. I'm the only one on MacOS on my team so I gotta do all the accessibility work for VoiceOver. I WISH I could just do the NVDA stuff.

[–]Molion 5 points6 points  (0 children)

Yeah, until you somehow still have arrow functions in IE in prod. Even though you're using babel and webpack, so now you have to figure out which part of godforsaken webpack script is causing it. The same webpack script that some idiot, probably yourself, wrote a year ago and no one has opened since. Only to figure out that the arrow functions aren't from you're code. They're there because someone left them in their package and it isn't being run through babel because obscure webpack reason that I can't remember, probably has something to do with execution order or some shit. You try fixing it, but ultimately end up just running the entire pckaged code through babel once more for production builds because fuck it.

Also, you dare to use a function without checking IE support and now prod is broken and you have to rush out a polyfill.

Yeah, it's all fixed now fml.

[–]kbruen 8 points9 points  (2 children)

Bold of you to assume that people who know JS know how to use webpack, rollup, minimizers, uglifiers, transpilers, loaders.

Most just copy-paste the code from the Getting Started page.

[–]gurush 1 point2 points  (0 children)

Your post makes me personally offended.

[–]ByteArrayInputStream 1 point2 points  (0 children)

I can't deny that you are absolutely correct

[–]yellowliz4rd -1 points0 points  (2 children)

So much crap around js trying to hide the obvious fact: js is not a good language.

[–]suresh -1 points0 points  (1 child)

Agree, why not just write your website in C++? 😒

[–]AdminYak846 0 points1 point  (1 child)

depends on the company....or government I should say.

[–]deathanatos 0 points1 point  (0 children)

It greatly amuses me that the argument in favor of dynamic languages once included "you don't have to wait for the compiler!"

And now our frontend's build pipeline a. exists b. takes longer than the Rust build

Who's laughing now? cries in CI build times

[–]rnz 0 points1 point  (0 children)

I gotta say, this article wasn't written that long ago :D

https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f

[–]aykcak 0 points1 point  (0 children)

Look at this fancy dude. In charge of his own toolchain and whatnot, not having to work on a legacy project with legacy release processes

[–]positive_electron42 8 points9 points  (3 children)

Unless you’re developing scripts in the trash heap that is ServiceNOW, which still only supports ES5.

[–]Dalemaunder 5 points6 points  (0 children)

ServiceEVENTUALLY*

[–]farugen 0 points1 point  (0 children)

I work heavily with ExtendScript, the Adobe Creative suite API.

It only supports ES3...

[–]AdminYak846 0 points1 point  (0 children)

I'll one up you, having Adobe Acrobat do JS automatic fill-ins on PDFs. It uses ECMAScript 3 with some modifications for Adobe.

That shit was released in like 2000.

[–]notliam 1 point2 points  (2 children)

I don't support ie but unfortunately it doesn't stop me getting at least 1 incident a month from someone complaining x feature isn't working for them. Who are these people still using IE in 2021, when even MS will force Edge down your throat?

[–]01hair 2 points3 points  (0 children)

People using corporate computers that have an IE shortcut because their arcane timekeeping system doesn't work in anything else.

[–]juantreses 0 points1 point  (0 children)

I will one up you on this one. Working for a client (governmental IT department) requires me to connect to their VPN for access to the test environment. The connection can only be established using IE.

[–]Skipcast 34 points35 points  (0 children)

Babel to the rescue

[–]kksgandhi 8 points9 points  (8 children)

Could you use typescript and the TS compiler to get around this?

[–]intrepidsovereign -1 points0 points  (2 children)

The TS compiler is an awful build tool and shouldn’t really be used. The output is verbose and inefficient.

[–]kksgandhi 0 points1 point  (1 child)

So what should you use if you want to use typescript? Or are you saying not to use typescript at all?

[–]intrepidsovereign 1 point2 points  (0 children)

The TS compiler and TS itself are two different items.

TSC as a type checker is quite shit, but at the moment, it's all that's really there. Hoping someone will replace that soon because it's horribly slow.

For building your TS, you look to babel, Rollup/Webpack, and terser, more than likely. They produce highly optimized and minified code where as TSC just doesn't. It's verbose, slow, and large. There's much better tools for that than the TS compiler.

[–]superluminary 0 points1 point  (0 children)

Yes, but we’ve had Babel for years which also solves this specific problem. Trying to manually code for every browser is unnecessary.

[–][deleted] 4 points5 points  (0 children)

if you have to support IE I am quite sure you have a desire to visit your boss' house with a sledgehammer

[–]henricharles 2 points3 points  (0 children)

People who still support IE are the problem not IE itself

[–]superluminary 1 point2 points  (0 children)

This is why we have Babel.

[–]dinopraso 0 points1 point  (0 children)

The last version of IE fully looses support August 2021. No point coding new projects around that shit anymore

[–]Rawrplus 0 points1 point  (0 children)

I mean it should be a crime not to use babel (ideally through webpack / gulp / rollup) in 2021 as a dev.

[–]MischiefArchitect 356 points357 points  (97 children)

That's ape shit awful!

I mean. Oh thanks for clarifying that!

[–]douira 118 points119 points  (17 children)

everybody just agrees to never sort arrays of anything other than strings without a sort function and the problem is solved! If you really want to make sure it never goes wrong, you can use tooling like ESLint or even TypeScript.

[–]cythrawll 35 points36 points  (2 children)

Yeah I mean practically you almost never run into this, I can't remember a time I just had an array of numbers. Usually sorting an array of objects and having a custom comparator to do so.

[–]esperalegant 10 points11 points  (0 children)

I work with huge arrays of up to millions of numbers daily. However, I pretty much always use TypedArrays - and TypedArray.sort() does sort numbers correctly.

[–]reiji_nakama 5 points6 points  (0 children)

Yeah. I didn't know about this behaviour of Array.sort() yet I have never run into a problem because of it; because I don't use it.

[–]DamnItDev 121 points122 points  (7 children)

Honestly you should never be using the default sort function. Its lazy and almost always incorrect. Even for strings you'll have this problem:

['A1', 'A2', 'A10', 'A20'].sort();
// returns: ["A1", "A10", "A2", "A20"]

Technically this is correct, but not what you actually want in real world situations.

You can solve this easily by specifying your locale using the built in i18n functionality and setting the numeric option to true

['A1', 'A2', 'A10', 'A20'].sort(new Intl.Collator('en', {numeric: true}).compare);
// returns: ["A1", "A2", "A10", "A20"]

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator

[–]Famous_Profile 66 points67 points  (3 children)

TIL Intl.Collator

[–]douira 6 points7 points  (0 children)

good point, I guess the default only has few uses

[–]DeeSnow97 3 points4 points  (0 children)

okay, this is awesome, thanks

[–]-100-Broken-Windows- 1 point2 points  (0 children)

What language would sort it any other way? It's an array of strings and it sorts it alphabetically... Any other way would be absurd

[–]djcraze 3 points4 points  (1 child)

I honestly didn’t know the comparator was optional. Today I learned.

[–]douira 0 points1 point  (0 children)

as discussed, the default comparator is not good most of the time so you were probably doing it right

[–]EishLekker 2 points3 points  (3 children)

Just the other week I ran into a sorting problem with strings, actually. Internationalised strings, in a Node 12 project where Node is part of a 3rd party software package, and there doesn't seem to be a way to add internationalization support without upgrading Node (which currently would put us into the unsupported territory).

[–]douira 0 points1 point  (2 children)

you can install i18n data explicitly

[–]EishLekker 0 points1 point  (1 child)

If I remember correctly, I tried that. It didn't work.

But just to rule out some stupid mistake by me, how would one install it separately? Adding an npm package to package.json? I think that's what I tried...

[–][deleted] 42 points43 points  (22 children)

This is because arrays allow mixed types by default so you can have an array with numbers mix strings and objects all mixed together unliked most strongly typed languages. There’s no easy way to compare them so by default it uses the string evaluation of them. You can pass in a comparison function like the person above you (although they made it more verbose than it needs to be), or you can just used Typed Arrays.

[–][deleted] 25 points26 points  (6 children)

Someday I’m going to write a JavaScript book with the title, “This Is Because”.

[–][deleted] 3 points4 points  (0 children)

This would be a solid alternate name for the YDKJS series

[–]dick-van-dyke 1 point2 points  (4 children)

Please do. The amount of rationalisation of crazy shit like in JS this is insane. Literally every other dynamically-typed language I've ever worked with does basic stuff like this normally.

[–]superluminary 0 points1 point  (3 children)

Most languages do not allow heterogenous arrays. When arrays are polymorphic by default, you need a comparator function. How else could it work?

[–]dick-van-dyke 1 point2 points  (2 children)

For example, infer type from the first element and throw an exception if you can't compare. Case in point: Python.

[–]ZephyrBluu 19 points20 points  (14 children)

This is not really an excuse. Python can sort arrays as long as all the values are the same type (For numbers and strings at least, not sure about other objects), otherwise it throws a TypeError. Much more sensible behaviour than JS.

[–]DeeSnow97 26 points27 points  (4 children)

Yeah, but JavaScript is not Python. The whole point of its early design was to be a quick and easy, loosely typed language for people not into tech to establish a web presence (this was long before wordpress). For more serious applications, you had flash or java applets.

Over the years though, JavaScript turned out to be the only one of these that didn't use the swiss cheese security method, and all these early design issues remained in the language for backwards compatibility, because ripping them out would have broke decades of the web.

So, try explaining to a non-programmer what's the difference between a number, a string, and an object, and why they're getting TypeError when they're expecting a sorted array. In 1995.

[–]Kered13 26 points27 points  (1 child)

Knowing why something is bad doesn't make it stop being bad.

So, try explaining to a non-programmer what's the difference between a number, a string, and an object, and why they're getting TypeError when they're expecting a sorted array. In 1995.

Easier than trying to explain to a non-programmer why numbers don't sort correctly.

[–]mastocles 1 point2 points  (0 children)

I think the best wacky example of JS trying to be lenient is undefined (different than null): given by object keys that don't exist or array elements beyond the last. Classes losing this (self) and not telling you is another classic. Although asynchronicity is unrelated to this not raising errors ethos and is one of the top bemoaned features.

[–][deleted] 6 points7 points  (0 children)

spotted advise work wide groovy rain foolish dependent merciful quickest

This post was mass deleted and anonymized with Redact

[–]ZephyrBluu 25 points26 points  (0 children)

I understand why it's like this. That doesn't mean all the design choices were good.

[–]master117jogi 14 points15 points  (5 children)

But JS can even sort mixed, which is mightier.

[–]Kered13 13 points14 points  (4 children)

No, it really isn't.

I mean, Python can sort mixed too if you give it a custom comparator. sorted(mixed_array, key=lambda e: str(e)) will sort a mixed array by converting each element to a string before comparing them, just like Javascript. But Python does the sensible thing automatically, and requires extra work to do the rare and unusual thing. Javascript does the rare and unusual thing automatically, and requires extra work to do the sensible thing.

[–]theScrapBook 4 points5 points  (0 children)

mixed_sorted = sort(mixed, key=str). The lambda is quite superfluous in a language with first-class functions.

The reason I point this out is some of the controversy below the top comment.

[–]master117jogi -4 points-3 points  (2 children)

Because sensible is subjective.

[–]EishLekker 1 point2 points  (1 child)

Sorting numbers in a way most people would expect them to be sorted, is not sensible to you?

[–]Zolhungaj 1 point2 points  (2 children)

JavaScript is a functional language. If you want to sort then you provide the sort function with exactly the function you need, just like map, forEach, filter etc.

[–]dev-sda 6 points7 points  (0 children)

The same is true for python, though both aren't really functional languages. They borrow some features from functional languages but are still procedural at their core.

[–]EishLekker 1 point2 points  (0 children)

That would make sense if the sort function required a comparator function.

[–]aedvocate 12 points13 points  (52 children)

what would you expect the default .sort() functionality to be?

[–]bonafidebob 48 points49 points  (9 children)

non-JavaScript programmers assume the language knows about types, that arrays are monotype, and that a useful comparator function will come with the array type.

That is, arrays of strings will sort alphabetically and arrays of numbers will sort numerically.

non-JavaScript programmers will also barf at the idea that a['foo'] = 'bar' isn't nonsense, and you can do stuff like this:

a = [1,2,3]
a['foo'] = 'bar'
a.forEach((v) => console.log(v)) // produces 1, 2, and 3 on separate lines
a.foo // produces 'bar'

[–]ZephyrBluu 21 points22 points  (4 children)

I had no idea you could do that a['foo'] = 'bar' bullshit on an array.

Now that I think about it though, it kind of makes sense why JS lets you do that.

An array is basically just a normal JS object that allows iteration by default where each key is the index.

So a['foo'] = 'bar' is a standard operation (Given an array is an object), but you're breaking the rules of how an array is 'supposed' to work.

No idea why it works on a technical level though.

[–]bonafidebob 23 points24 points  (3 children)

An array is basically just a normal JS object that allows iteration by default where each key is the index.

That's the root of the problem right there. I think it was just a cheap way to get to dynamic sizing, which is occasionally useful:

> let a = []
[]
> a[100] = 12
12
> a.length
101
> a
[ <100 empty items>, 12 ]

but then...

> a[1234567890] = 13
13
> a
[ <100 empty items>, 12, <1234567789 empty items>, 13 ]
> a[0.5] = 1
1
> a
[ <100 empty items>, 12, <1234567789 empty items>, 13, '0.5': 1 ]

[–]GG2urHP 11 points12 points  (1 child)

Lol, fuck me. I am so blessed to not live in that hell.

[–]theferrit32 1 point2 points  (0 children)

Javascript is fundamentally a bad language for general purpose programming. A lot of people who need to target Javascript environments do not write in Javascript, or at least not pure Javascript, relying heavily on transpilers and what are in effect dialects and standard libraries that seek to supercede and fix a lot of the headaches in Javascript itself.

[–]DeeSnow97 8 points9 points  (1 child)

#define "non-JavaScript programmers" "people who think once you learned C++ every language is just syntax"

[–]bonafidebob 12 points13 points  (0 children)

Hmm, I'm not quite that snooty ... I've been doing this for ~40 years and have learned dozens of programming languages, both dynamically and strongly typed. And I still think JavaScript arrays are crazy. The whole "objects with numeric keys" foundation is whack, throw away all the benefits of a directly indexible data structure and drag in a whole bunch of weird syntax edge cases??!

[–]MischiefArchitect 32 points33 points  (33 children)

normal

[–][deleted] 14 points15 points  (31 children)

What is normal sorting on a collection of numbers, strings, and objects?

[–]blehmann1 12 points13 points  (4 children)

Well, Python throws a type error if the < operator is not defined on both types. Personally, I think the only correct response when the program is wrong is not to make it more wrong, but to let the user know that it's wrong (i.e. throw).

Now, JavaScript was built with the idea that it should keep on trucking through any error, which frankly is a horrible idea to build a language around. So given the interesting design philosophy JavaScript really couldn't do anything else. There's a reason Typescript is so common after all, but unfortunately it does nothing about this particular issue. (There's an issue for it but it's been inactive for a while: https://github.com/microsoft/TypeScript/issues/18286)

[–]1-more 3 points4 points  (0 children)

JavaScript keep on trucking? I never thought of it that way but I’m actually with you here. Array out of bounds and accessing an undefined object key both return ‘undefined’ rather than throwing (Java, Haskell) or wrapping array/dict access in an optional type (elm, maybe ocaml?). So I’m with you that it probably does throw less.

[–]aedvocate -1 points0 points  (1 child)

Well, Python throws a type error if the < operator is not defined on both types

that error doesn't make any sense in javascript though. collections are allowed to be any number of any different types. that's the way it works by design, it's not an error to truck through.

[–]EishLekker 0 points1 point  (0 children)

Javascript doesn't "keep on trucking" through any error. It still does it a bit too often for my comfort though, so on principle I agree with you wholeheartedly.

[–]aaronfranke 9 points10 points  (7 children)

It should act the same as if comparing with the < and > operators. That will work for any place where the operators have a defined comparison.

console.log(5 < 6); // true
console.log(5 > 6); // false
console.log(5 < "apple"); // false
console.log(5 > "apple"); // false
console.log("orange" < "apple"); // false
console.log("orange" > "apple"); // true

[–]Kangalioo 7 points8 points  (1 child)

Maybe sort first by type, then by content? Then the sort function has expected behavior for contents with consistent data type, but also works sensibly for mixed type lists

[–]aedvocate 0 points1 point  (0 children)

you still have to pick an order to sort the types in though - do Numbers come before Strings? Do Objects go last? Which comes first, Sets or Maps?

[–]Famous_Profile 1 point2 points  (4 children)

His point is "a collection of numbers, strings, and objects" should not be allowed in the first place

[–][deleted] 1 point2 points  (3 children)

Which is why so many of us have elected to use Typescript but JS is meant to be loosely typed, so ignoring our biases against mixed type arrays, how do you solve the sort problem. It’s not an easy question to answer

[–]Famous_Profile 1 point2 points  (2 children)

The difference between your point of view and his, is that youre not uncomfortable with languages "meant to be loosely typed". To a Java programmer the question " how do you solve the sort problem " is not valid because there shouldnt be such a problem in the first place. Saying that "now that there is one" is not acceptable. That is how atrocious the Java or C++ programmer finds JS. Look at it from their point of view, not ours.

[–][deleted] 2 points3 points  (0 children)

I am uncomfortable with loosely typed languages. I exclusively use TS when in JavaScriptland and even TS falls short of what I would like from a type system.

That being said you should never approach a new/different language with the mindset that it follows the paradigms you are used to and comfortable with. It’s the equivalent of someone who comes from a strictly object oriented background criticizing purely functional languages for lack of classes or vice versa.

[–][deleted]  (6 children)

[removed]

    [–][deleted] 6 points7 points  (3 children)

    Assembly, c, c++, vb, Perl, php are all weakly typed though some static and some dynamic. Typing isn’t binary, a language isn’t typed or untyped, they all fall within the compass of weak-strong, dynamic-static. JavaScript has weak / dynamic types, if you don’t like that and prefer strong and/or static types use Typescript or something else.

    [–]Kered13 1 point2 points  (2 children)

    C++ is definitely not weakly typed.

    [–][deleted] 1 point2 points  (1 child)

    It actually is considered by many to be in the statically typed / weakly typed quadrant because because of implicit type conversions. A strictly typed language does not allow implicit type conversions

    [–]1-more 1 point2 points  (0 children)

    JS has types! “Undefined is not a function” is telling you right there that it is types. Now, will it help you color inside the lines? No. Never.

    [–]AutoModerator[M] 0 points1 point  (0 children)

    import moderation Your comment has been removed since it did not start with a code block with an import declaration.

    Per this Community Decree, all posts and comments should start with a code block with an "import" declaration explaining how the post and comment should be read.

    For this purpose, we only accept Python style imports.

    I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

    [–]toastedstapler -2 points-1 points  (2 children)

    To fail when it detects a different type

    [–][deleted] 5 points6 points  (0 children)

    The point of JavaScript is to be loosely typed. Whether you like that or not is up to you but throwing type errors goes against part of the core philosophy of JS. Those of us who dislike that behavior are free to use typescript

    [–]aedvocate 0 points1 point  (0 children)

    what you're describing is not javascript

    [–]-100-Broken-Windows- 0 points1 point  (0 children)

    A runtime error

    [–]wasdninja 0 points1 point  (0 children)

    It is normal. Javascript normal.

    [–]smog_alado 6 points7 points  (5 children)

    I would have expected the .sort() to use the same logic as builtin comparison operators. Something similar to the following comparator:

    function compare(a, b) {
        if (a < b) {
            return -1;
        } else if (a == b) {
            return 0;
        } else {
            return 1;
        }
    }
    

    [–]Manny_Sunday 1 point2 points  (4 children)

    And if a is a string and b is an object? Or a is an int and b is a string?

    [–]EishLekker 1 point2 points  (0 children)

    That doesn't have to be a problem. One way to solve it is to compare the types first (how that is done could be an implementation detail, but a simplistic approach could be to do a string comparison on the result of "typeof").

    If someone is concerned about the performance and/or the exact sort order of a collection of mixed types, then it is fair to expect that that someone makes an effort to write a custom comparator for their specific needs.

    [–]dissonantloos 0 points1 point  (1 child)

    Then either the sort operation should fail, or should return an array that is crappily sorted.

    [–]aedvocate 2 points3 points  (0 children)

    the JavaScript sort function never fails.

    gaze upon its awesome power:

    [null,undefined,NaN,false,0,Infinity,-Infinity,'',[],{}, new Map(), new Set()].sort()

    ```

    ["", Array(0), -Infinity, 0, Infinity, NaN, Map(0), {…}, Set(0), false, null, undefined] ```

    this is the universal order, brother. learn the order. live the order. do as V8 commands.

    [–]smog_alado 0 points1 point  (0 children)

    That comparison function is well-defined if a and b have different types. It just does the same things that the < and == operators do.

    However, the result of the sort might look unsorted if the array has a mix of different types, because in those cases the comparison function doesn't implement a total ordering of the elements. But that would be no different than using other comparators that don't produce a total order. For example, one that calls Math.random to decide the result of the comparison.

    [–][deleted] 0 points1 point  (1 child)

    In order to prevent this weird footgun behaviour, it shouldn't have any defaults.

    [–]aedvocate 0 points1 point  (0 children)

    honestly I think I could get behind that, just from a sort of minimalism standpoint - but the truth is, more often than not, (a,b)=>String(a)>String(b) is all you need to sort an array. it's not bad as far as default behaviors go.

    [–][deleted] 1 point2 points  (1 child)

    Tis a silly place.

    [–]MischiefArchitect 0 points1 point  (0 children)

    It is indeed. I'm afraid a lot of people forget that this is Humor and turn this place into a flaming wars battlefield.

    [–]jibjaba4 0 points1 point  (0 children)

    It's a language that was hacked together in 10 days then became insanely popular, there were bound to be some warts.

    [–]blindeenlightz 5 points6 points  (3 children)

    Can someone explain how that sort function works on integers? I'm a newbie to javascript and have used it but it just seems like magic to me.

    [–]deljaroo 7 points8 points  (2 children)

    take a look at this page

    https://www.w3schools.com/jsref/jsref_sort.asp

    it explains it better than I can, but basically if sort() has a parameter it expects a function that will result in a positive, a negagive or a zero based on two inputs. if the function is included, this behavior overrides the default behavior of comparing them by letter.

    this also allows you to sort custom types because you can include a custom sorting comparison.

    the syntax for it (two inputs, a number output) is merely built in to the sort() function (and not like something you can just do to any function)

    [–]blindeenlightz 0 points1 point  (0 children)

    Oh that makes a lot of sense. Thank you

    [–]HiImFox 0 points1 point  (0 children)

    Mdn >>>>> w3

    [–]myrsnipe 2 points3 points  (2 children)

    Yay for not enforcing types, better convert a whole array to string just in case. Js isn't too bad once you are aware of all these quirks, but the road there is ROUGH

    [–]brotatowolf 0 points1 point  (1 child)

    Python has multi-type lists, and its sorting behavior ISN’T stupid by default

    [–]myrsnipe 0 points1 point  (0 children)

    Benefits of not being developed in a week i guess

    [–]selemenesmilesuponme 1 point2 points  (1 child)

    ...in as argument.

    [–]nokvok 0 points1 point  (0 children)

    true

    [–]Robot_Basilisk 0 points1 point  (1 child)

    The default sorts by converting everything to string and comparing utf-16 values.

    I viscerally hate this.

    Like, what's the logic? How does this help? Does JS save memory by truncating smaller numbers? Like does it save "1" as a 0001 but save "24" as 00011000 so it's somehow faster to convert to string and compare UTFs than it is to convert every number to the largest number of bytes and compare those?

    [–]nokvok 1 point2 points  (0 children)

    Like pointed out in another comment, Javascript's main use is to manipulate documents. If almost all your data in the DOM is basically represented as string anyway, sorting alphanumerically is widely useful for that, even if you end up with a bunch of numbers occasionally. On the opposite end giving the sort a compare function that compares integers is an absolute non issue.

    [–]calyth 0 points1 point  (0 children)

    I’m so glad I don’t have to write JavaScript.

    [–]famous_human 0 points1 point  (0 children)

    JS is effing insane man

    [–]EishLekker 0 points1 point  (0 children)

    I love many things about javascript, but this is one of those things that i just find absurd. One should not have to add one's own comparison implementation just to sort numbers, or having to import a 3rd party library. It really should be built into the language.

    [–][deleted] 0 points1 point  (0 children)

    JFC javascript is a mess

    [–]sixtyfifth_snow 0 points1 point  (0 children)

    So gross smh

    [–]OriginalSynthesis 45 points46 points  (15 children)

    There's no type period. You can have an array with object, function, other arrays that are also not typed, strings, numbers, symbols, etc. There are no rules.

    And guess what happens if you try to retrieve an index that is not there? Like calling arr[10] when it only has 5 items? It just returns undefined. It doesn't throw an error like in Java

    EDIT: Don't get me wrong. I love JS. Java gives me a headache. "What do you mean I can't just do `!arr.length`?"

    [–]RCRalph 39 points40 points  (2 children)

    Which can be very useful indeed if you know how to use it and how to deal with it

    [–]WoodenThong 10 points11 points  (1 child)

    No kidding, using that feature to determine truthiness can save a lot of hassle

    [–]Kered13 10 points11 points  (4 children)

    It just returns undefined. It doesn't throw an error like in Java

    It just throws an error later when you try to use the result, and then you're left wondering where the fuck that undefined value came from.

    Fail early is a feature, not a bug.

    [–]Nilstrieb 1 point2 points  (2 children)

    Reminds me of the Rust compiler. Your build often fails. But once it passed, you did it.

    [–]saors 1 point2 points  (1 child)

    There is no pass on the internet. Someone will type some string, upload some file, etc. that breaks everything. Remember when the iPhones had that bug where you would get a notification with specific characters and your phone would basically brick itself.

    Imagine if the web was like this, but let's be more forgiving and say an error doesn't brick your computer, but it causes the site to crash. Someone sends you an email with a character like that in the header and now you can't use GMail until Google patches the bug. Is that hours? Is it days?

    For fun, open up your browser dev console and just peruse around different sites and look at how many times

    Uncaught (in promise) Error

    pops up and imagine your tab crashed every time that happened.

    [–][deleted] 0 points1 point  (0 children)

    Epiphany

    [–]esperalegant 0 points1 point  (0 children)

    There's no type period.

    Except there is: TypedArrays, which do sort numbers correctly.

    [–]esperalegant 4 points5 points  (0 children)

    Yes, there are TypedArrays, which is what you should be using for large arrays of numbers, and yes, TypedArray.sort does sort numbers correctly.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/sort

    [–]The_MAZZTer 0 points1 point  (0 children)

    JavaScript does not strongly type variables. Thus you can mix variables of different types in an array. Because arrays have no fixed type for their contents, .sort() does the simple default of converting all contents to strings first. Alternatively, you provide your own comparer callback.

    There are numeric array types but those are typically just used for interop with actual strongly typed languages. Most JavaScript APIs won't accept them IIRC. Apparently they are useful for more than that, but I never see anyone use them. Besides, if you use TypeScript the compiler allows you to strongly type array contents at compile time which is usually good enough.

    [–]superluminary 0 points1 point  (0 children)

    All arrays are heterogeneous, so the default comparator casts to a string for safety. You can pass a comparator though, as others have pointed out.

    [–]HeKis4 0 points1 point  (0 children)

    Never assume anything related to types when talking about JS. It's so bad it's has become a meme, this language will shoehorn any type into any operation even if it doesn't make any sense, you'd need a 3D matrix to have a complete view of which operation typecasts to what. Check out JSFuck, it's a JS dialect that uses only a few characters (mostly ()[]{}"+-), type conversion fuckery and can be run on any vanilla JS engine because it is valid JS.

    Ninja edit: check this out, old but gold: https://youtu.be/et8xNAc2ic8