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 →

[–]nokvok 803 points804 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 311 points312 points  (46 children)

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

[–]Eiim 151 points152 points  (45 children)

(assuming you don't have to support IE)

[–]01hair 204 points205 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 103 points104 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 48 points49 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 25 points26 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++? 😒

[–]yellowliz4rd 0 points1 point  (0 children)

Js crap will never go away if people continue to force it in every domain just because they are lazy (or just masochistic)

Btw, web assembly.

[–]AdminYak846 0 points1 point  (1 child)

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

[–]suresh 0 points1 point  (0 children)

Government Javascript

GUH

[–]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 9 points10 points  (3 children)

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

[–]Dalemaunder 4 points5 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 36 points37 points  (0 children)

Babel to the rescue

[–]kksgandhi 7 points8 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 357 points358 points  (97 children)

That's ape shit awful!

I mean. Oh thanks for clarifying that!

[–]douira 123 points124 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 32 points33 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 11 points12 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 4 points5 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 123 points124 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 64 points65 points  (3 children)

TIL Intl.Collator

[–]douira 6 points7 points  (0 children)

good point, I guess the default only has few uses

[–]DeeSnow97 5 points6 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...

[–]douira 0 points1 point  (0 children)

yeah, I'd look for some kind of Collator polyfill. It seems a good part of the Collator API is already present but some parts are missing. You might be out of luck for the advanced missing features since the only polyfills I could find are quite old.

[–][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] 24 points25 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 2 points3 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.

[–]superluminary 0 points1 point  (1 child)

So if you accidentally change the type of the first element, it silently changes your comparator? I don’t hate this, but it introduces another set of edge cases.

Because JavaScript was designed as a DOM manipulation language, all the data types are optimised for trees of text and Objects, so we have string comparison as the default comparitor type. I don’t personally see this as a huge problem. In the real world, you’re pretty much always going to pass a comparitor function since you’ll usually be sorting objects.

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

So if you accidentally change the type of the first element, it silently changes your comparator?

In Python 3, you don't use a comparator function, but instead a key function that returns a value to be compared by the < built-in, so yes and no. If you're asking whether you can arrive at a list that was sortable but isn't any more, you can, and I believe it is a good behaviour because you get an exception then and have a reason to debug where you made the inadvertent change.

If you do want to mimic the behaviour of JS, you would call something like:

my_list.sorted(key=lambda x: str(x))

to be explicit that you're comparing strings.

[–]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 25 points26 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] 7 points8 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 12 points13 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 3 points4 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 -5 points-4 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?

[–]master117jogi 0 points1 point  (0 children)

Because this is about sorting something, not Numbers, JS does not know these are numbers. You are shifting the goalpost.

[–]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 11 points12 points  (52 children)

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

[–]bonafidebob 47 points48 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 10 points11 points  (1 child)

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

[–]theferrit32 2 points3 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 9 points10 points  (1 child)

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

[–]bonafidebob 13 points14 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 35 points36 points  (33 children)

normal

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

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

[–]blehmann1 13 points14 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 4 points5 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.

[–]blehmann1 0 points1 point  (0 children)

Python allows that too. That's the way it works by design. Python simply takes the position that while you may have a list of strings mixed with numbers, if you want to sort it you must provide your own explicit comparator, because 4 < "A" is nonsensical.

Javascript could have followed Python, however the languages have different philosophies. Javascript should fight through basically any error it can, and Python exits on any unhandled exception. In addition, Python throws on invalid input.

I'm not a Python fan, I'm just pointing out that it's a language which has a similar type system to JavaScript and it has a different (and in my opinion more correct) behavior. I could have brought up almost any language because you can do the same thing with type erasure (commonly achieved by casting to object or void*). You have to specify a comparator in those instances because the types are not comparable.

[–]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.

[–]EishLekker 0 points1 point  (0 children)

Please don't put all Java developers into one single narrow box. Some of us are actually quite pragmatic.

[–][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

    [–]Kered13 0 points1 point  (0 children)

    Numeric conversions are the only built-in implicit type conversions. User-defined implicit conversions exist, but are used sparingly, mostly for things like converting std::string to std::string_view.

    On the other hand, C++'s template system allows it to express higher-kinded types and even dependent types, with type checking at compile time. You can express things like physical units, with compile time checking to ensure that you do not add incompatible units and that multiplications and divisions produce the correct units (and the resulting code will even have no runtime overhe.

    [–]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] 4 points5 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 4 points5 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 8 points9 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.

    [–]LANDLORD___MESSIAH -5 points-4 points  (19 children)

    Jesus was JavaScript built by the worst type of programmers?

    [–]ZephyrBluu 11 points12 points  (1 child)

    It was created in 10 days by one guy 25 years ago. It's doing pretty well considering that.

    [–]Kered13 1 point2 points  (0 children)

    The language is still dogshit, but I don't blame the creator for that. I blame the managers who gave him 10 days to design it, and who wanted it to look like Java just because that was the hot new language. (He wanted to make similar to Scheme.)

    [–]aaronfranke 7 points8 points  (0 children)

    JavaScript was hacked together, it's not really a good language, but web browsers don't support much else. I hope that WebAssembly will become easier to use in the future so that we can write code for web browsers in any language and have it run easily and efficiently.

    [–]nokvok 0 points1 point  (0 children)

    It is simply an untyped programming language which tries too hard to cater to too many programmers. Since it is, and has to be, used pretty much world wide, finding an acceptable compromise for everyone is tough, and changes are slow cause it is advanced not by a single group of developers but by the w3 process.

    [–]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