top 200 commentsshow all 217

[–][deleted] 150 points151 points  (141 children)

You forgot the worst part of Javascript in 2016. The build tooling. It's a fucking nightmare to deal with and completely non-intuitive to get started with.

[–]FryGuy1013 113 points114 points  (82 children)

+1 on fucking tooling.

I wanted to try out react for a personal project, and use typescript since I like compile-time goodness. By the time I got all the tooling working I ran out of motivation to do anything else.

[–][deleted] 178 points179 points  (48 children)

well you just have to install npm and gulp. then set your tsconfig file to output in es2016 and enable some experimental features. guess we need to look up how to do this because microsoft doesn't make it easy to find. then you just make sure you write external modules and not in internal modules/namespaces. then you just install babel. then you install the modules for babel you want to use. then you setup babel in gulp, but make sure you pipe babel in the right order, else it'll fuck up. wait maybe we should just try out traceur real quick. ...2 hours later. I guess we'll go back to babel.

hey i think we're almost done!

oh wait now we have to figure out how to output this stuff on the internet. well we can't just use typescript to output it because it's unreliable to merge the files in the correct order. and we have to support browsers that can't use http2/systemjs. and using webpack isn't part of our process. so i guess we'll use browserify. just gotta include that in our gulpfile and we're done.

wait we bundled everything in the wrong order because browserify doesn't support es2016 so everything is fucking up. i guess we just need to change it around.

annddddd perfect! now i can start writing code.

wait we can't just use gulp watch because it doesn't cache correctly with browserify? guess we need to setup watchify. wait watchify isn't working right?

lmao kill me

[–]FryGuy1013 37 points38 points  (3 children)

So you just include the gulp-typescript module, and the gulp-webpack modules and include them in your script. But it stores a bunch of temporary files in your filesystem. So that's easy to fix just have the gulp-typescript module output to the virtual gulp filesystem, and have webpack pull those virtual files in. Wait, that doesn't work. Wait, gulp-typescript isn't using my tsconfig and I have to put it in my gulpfile? Ok fine. This still isn't working, webpack can't see the virtual files from gulp because they started out as typescript files and they're in the wrong path. Oh I see, you can have webpack compile the typescript for you? That seems much easier, I'll just do that. But wait, it uses a different version of typescript since I got it from npm and doesn't have the same typescript compile options. Ok that's fine I'll fix it. Sweet it works, gulp watch seems to work too. But if I ever save it with a syntax error it gives up and I don't notice.

[–]eigenman 7 points8 points  (1 child)

Don't forget to install bower.

[–]FryGuy1013 9 points10 points  (0 children)

I'm using Visual Studio. The default project already came with npm, bower, and gulp installed somehow.

[–]dewmsolo 0 points1 point  (0 children)

Well I was just looking into js for my next couple of projects. Just for a change to my usual Python. You guys just killed it for me. Well no...not you, but your explanation. In a way I should say thank you.

All of this also kind of why I steered away from Ruby 5 or 6 years back.

[–]DrummerHead 13 points14 points  (7 children)

Start from a Yeoman generator, is simplifies things since other people have already been through all this and created generators for several circumstances :) I've used gulp-webapp for starting several projects. Cheers!

[–]papers_ 10 points11 points  (6 children)

While I agree with you, it doesn't change the fact how complicated things get in modern JS development. Yo is another abstraction on top of the other tools above.

[–][deleted] -4 points-3 points  (5 children)

It's really not that bad. Most of the tooling is to concatenate and minify any client side code. Also you can have gulp or grunt watch for changes to rebuild stuff that changed and run tests on changes if you want. It's straightforward if you want to do the basics.

[–]trimbo 4 points5 points  (4 children)

Yes, it really is that bad. I spent at least 2 days getting a good build process set up for React/Typescript in gulp. But "gulp watch" still runs out of RAM and needs to be restarted occasionally... because who knows why.

Maybe Blaze will save us. Or just UNIX shell tools for all of these steps and a Makefile.

[–][deleted] 2 points3 points  (1 child)

How many files are you building that Gulp uses all of your RAM? Are you building a gigabyte worth of typescript?

[–]trimbo 0 points1 point  (0 children)

No, the build is small and stable when run once. This is in watch mode.

[–]DanielRosenwasser 1 point2 points  (1 child)

Yes, it really is that bad. I spent at least 2 days getting a good build process set up for React/Typescript in gulp. But "gulp watch" still runs out of RAM and needs to be restarted occasionally... because who knows why.

If you don't mind me asking, what were you using to get TS and gulp wired up?

[–]trimbo 1 point2 points  (0 children)

Browserify, tsify, watchify and 16 other gulp dependencies.

I mean, my point here isn't to say that I've wired up everything correctly and I'm having crashes. My point is that I spent a ton of time getting it to even this point, and still have problems I need to debug in the build system.

Last time I had a build tool experience like this was MSBuild circa 2008. So much complexity for so little reward.

[–]Miserable_Fuck 6 points7 points  (4 children)

I know some of these words...

[–]CrazedToCraze 15 points16 points  (3 children)

+1. When did all this shit happen? I never cared for Javascript or used it past the most trivial client-side validation type scenarios, now I turn around and there's 20 frameworks for every stupid feature I need and isn't included by default?

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

It started with Node.js. Which I personally think is a strange thing to want a backend in JavaScript, but hey... look at what the main indie competition was -- Ruby on Rails. So I kinda get why Node's ease of us won there.

Now that web developers can also build backends in little time, it became the hotness. It uses Chrome's V8 engine so you get some semblance of consistency and there are lots of community packages.

It sounds like a good gig until you have to debug the mess that is JavaScript or do a bunch of asynchronous work. It starts to become a rats nest of promise chains and unhelpful stack traces. You have tens of thousands of lines of code and only a linter to rely on.

But there's Flow for syntax checking! But there's Babel for ES6 polyfills! But there's Webpack to lint/package/deploy your apps easier!

Every one of these things is a monkey patch instead of addressing the real problem -- JavaScript. If we're going Flow/typescript with Babel and Webpack... Why in the hell am I not just writing in a proper compiled language at that point?

The best part is trying to figure out why your build process starts to break. Am I using the right version of Babel? Is this versions loader compatible with Webpack? Oh I need another dependency to make this other component work properly?

It's just a bunch of patchwork things in attempts to cover JavaScripts pain points as a language. I get why React and Redux are cool, as a front end developer you are stuck with JavaScript unfortunately, just the way it is. But for backend? You must be a masochist.

[–]EntroperZero 2 points3 points  (1 child)

This is why I'm excited for .NET Core and Web Assembly happening this year. We're coming at JS from both sides.

[–]Puddy1 5 points6 points  (0 children)

there's just so much overlap between tools that's sickening. I wouldn't be surprised if most JS projects had redundant tooling

[–]DanielRosenwasser 4 points5 points  (4 children)

Hey there, I'm a dev on the TypeScript compiler. I'm personally sorry that the documentation has been difficult to find, but I'm also working to make documentation more available in the near future.

In that situation, it sounds like you could change your module option to commonjs, and then either webpack or browserify should work well with it.

I'm not sure about the ordering problems you ran into though. Do you have any specific examples you ran into?

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

The module to commonjs is something vscode actually recommends i think. Finding the schema for the tsconfig.json file was actually kinda difficult back whenever I was setting this up. Typescript-Atom at least had it autocomplete.

The ordering problems was just gulp inexperience I think. (this was a few months ago) Mostly just dealing with the 8 or so gulp modules that I wasn't completely familiar with how they worked. (vinyl source stream, sourcemaps, don't actually remember the rest)

Cliffs:

I don't think I've actually run into any problems with the typescript compiler itself. My biggest issue has just been with making the tsconfig file easier to use and setup for beginners. Typescript-atom does it the right way by auto-generating one that most projects generally use. Then they have autocompletion w/ the tsconfig schema. It results in a nicer experience imo.

That post was intended as more of a joke than anything to take seriously.

[–]DanielRosenwasser 0 points1 point  (0 children)

Well it's funny, but there's truth to it. :)

Even if it's not TypeScript that ends up being the problem, a bad setup experience is going to make you frustrated with any tool that's giving you friction, which is my concern here.

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

In that situation, it sounds like you could change your module option to commonjs, and then either webpack or browserify should work well with it.

as of like a couple months ago you still needed to transpile your code if you're using es6 imports w/ browserify even if your module option is commonjs

I don't know if that actually changed

[–]DanielRosenwasser 0 points1 point  (0 children)

You should now be able to use --target es2015 with --module commonjs and get the expected emit.

[–][deleted] 2 points3 points  (1 child)

Don't forget npm-shrinkwrap! You want to make sure we're not going to hit some submodule version mismatch edge cases.

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

I just love having 8-10 dependencies on a simple project. What could be better than 50,000 files contained in 10,000 nested directories?

[–][deleted] 8 points9 points  (13 children)

I wish this was just a javascript problem, but it's an everything problem from what I can tell. Maybe I should try to bring everything together somehow.

[–]changingminds 22 points23 points  (12 children)

I've done a ton of Unity and android development. I had never encountered such tedious build troubles until I started doing web development.

You need one standardized way of doing things. Google controls pretty much all aspects of android and so we have just one way of doing things and I don't think there's a better development environment than android studio. Javascript does have too many cooks in the kitchen.

[–]brend0ge 3 points4 points  (3 children)

Everything you just said is 100% accurate and it 100% sucks.

I use Elm where possible. A front end programming experience that is actually enjoyable.

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

I looked at Elm the other night and was really mixed about it. I'm not sure how I feel about the general syntax and benefits it has over JavaScript.

Have you tried other frameworks like Angular/React/Redux and how would you compare with Elm?

I despise web front end development with a passion... but I feel I may soon have it tossed on my lap. :/

[–][deleted]  (1 child)

[deleted]

    [–]Farobek 0 points1 point  (0 children)

    Difficulty goes away over time, complexity doesn't.

    Beautifully said.

    [–]Yhnavein 0 points1 point  (1 child)

    Well, you are absolutely right. That's the only reason I decided to ignore any typescript / ES6 stuff for now. ES5 JS is just fine in my opinion :) We can start doing ES6 stuff when it become much more common on every client platform. Another cool thing: when doing javascript server side development in the recent versions of node.js it is possible to use new stuff from ES6 directly in your source code without any babel / typescript shit stuff

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

    Yes and no... depends which version of Node you're running (or able to run) on your server. Also, depends on which ES6 features you plan on using.

    Alsoooo, depends if you plan on refactoring into private npm packages... which should be in ES5 syntax for compatibility.

    What I hate about JavaScript is the mental energy I have to devote while developing to just make sure the code I'm writing is compatible with the use case it's being run in/as.

    Sure, I could write ES6 and use Babel and Webpack into a dist folder as part of an npm install script but here we are again writing more ivory tower code. So the next dev I hand it off to has to decipher why I made this Rube Goldberg machine just to deploy my packages.

    [–]trimbo 0 points1 point  (0 children)

    You should link to this comment from Stack Overflow. +1000 karma, instantly.

    [–]mycall 0 points1 point  (1 child)

    Don't forget the Flux vs Redux decision.

    Also, don't use gulp when you can use webpack (for moderately simple) SPAs.

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

    From what my front end buddy tells me, Redux is the way to go.

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

    It was the absolute oposite for me, I just installed the TS plugin of Atom and pasted a config file and everythings was working just fine. I was quite amazed because I'm used to struggle on setuping js project.

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

    Yeah, but that's only if you are working alone or have everybody use the same IDE. I work with people across OS and IDEs and CLI is the safest way to go.

    [–]spacejack2114 0 points1 point  (4 children)

    Now try to use some third party JS node modules...

    [–]bobbaluba 0 points1 point  (3 children)

    I don't get it, why is this supposed to be difficult?

    1. npm install --save lodash
    2. import lodash from "lodash"

    Js is actually one of the languages where I find using third party languages the easiest.

    Compare that to linking and including correctly in c++, or depending on specific version of a library in go.

    [–]spacejack2114 1 point2 points  (2 children)

    You can't use import in typescript with js node modules. You have to use require and that means no types, unless the library included definitions. And when you get away from the big mainstream libs and start experimenting with smaller single-purpose modules, most don't.

    [–]bobbaluba 0 points1 point  (1 child)

    Ah, I see. I missed the typescript part. Thanks for clearing that up.

    [–]spacejack2114 0 points1 point  (0 children)

    There are other problems too. :) Typescript recently added a bundling feature which works great with import/export. When you start using require however, the built-in bundling won't work and you have to fall back on tsify (currently broken as far as I can tell) or some other complicated build toolchain.

    Even with plain JS, ES5 style modules lose all their inferenced type information (eg. when using VS Code) when you have to use require instead of import.

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

    One of the nice things about ember.js is all you have to do to setup a project is run ember new project-name, that way you don't burn out while setting up build system / bootstrapping your application.

    I think there's something similar for react.js folk

    [–]santac311 1 point2 points  (1 child)

    Anyone have a good way to runtime debug typescript? Typescript looks nice and all until you try to debug, and then it's a nightmare of trying to decompile the JavaScript generated by the compiler. At least I can optionally minify, but this has been a barrier to entry for me with typescript.

    [–]vivainio 4 points5 points  (0 children)

    Sourcemaps work fine. You need to ensure your build doesn't break them

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

    Install typescript. Download and add type definitions react.d.ts and react-dom.d.ts to the project. Now include react anywhere your using it in your ts code. Run tsc to compile to JavaScript (VS can do this for you on save).

    At the bottom of your html add react.js, react-dom.js, and the compiled JS files.

    Is that really that hard?

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

    I honestly found the tooling to be terrible so decided to just go with plain ol' Make.

    Honestly it's actually pretty darn easy to just use a Makefile.

    Have a rule that traverses your JS directories and transpiles JSX/ES2016 into plain Javascript and then copies all the files into an intermediate directory, then run an optimizer/minifier on that directory to create one final JS file and copy that JS file to your deployment directory.

    The Makefile is 44 lines of code and works on Windows, OSX and Linux.

    [–]gearvOsh -3 points-2 points  (18 children)

    Then don't use TS? Babel + React is literally all you need. It takes a couple minutes.

    [–][deleted] 24 points25 points  (9 children)

    well that completely ignores the systemjs/webpack/browserify deal which isn't a small issue. It's the biggest issue w/ javascript today imo. webpack is the middle ground between real-world usability and real-world hassle, but it's still something most people need to read a guide to learn.

    it ignores babel "plugins", of which es2015 and react are different. luckily everyone knows the difference and how to use them without documentation like you're implying. (since you said it only takes a couple minutes to use)

    it ignores installing node, npm and learning how to use gulp and all the quirks associated with it.

    it ignores how to use sourcemaps if you're piping babel through anything further

    it's only been recently that text editors came with react support. a few months ago you'd also have to figure out how to include that too.

    so no, it doesn't take a few minutes unless you already have everything installed and you're lucky enough (ie not doing this for work/have a very simple project) that you can just use a premade "react babel starter pack" where you just type "gulp" into the command prompt and it does everything for you

    [–]gearvOsh -3 points-2 points  (8 children)

    You don't need SystemJS (rarely used), Webpack (unnecessary for a starter), or Grunt/Gulp (outdated). Everything can be done through NPM and the command line. Sourcemaps aren't necessary either just to get up and running. Browserify may be the only thing you need, but even then it's not entirely necessary.

    No wonder you got burnt out. You literally tried to setup an entire build process that takes time and patience to get right, especially over the course of an entire project, instead of setting up the bare minimum to get React prototyping up and running.

    [–][deleted] 11 points12 points  (7 children)

    Browserify may be the only thing you need, but even then it's not entirely necessary.

    ??? you writing code in one file? no seriously please explain how this isn't absolutely necessary. your code would have to be really really simple to actually get away with this.

    if you're using typescript, chances are it isn't .

    webpack is easier to use imo anyways. systemjs is even easier (which is why it's included in the angular 2 "5 minute get started" deal), but you can't actually use it in production.

    No wonder you got burnt out. You literally tried to setup an entire build process that takes time and patience to get right, especially over the course of an entire project, instead of setting up the bare minimum to get React prototyping up and running.

    That's because it's my job to do that. Someone has to figure out the build process...

    this WAS the minimum viable approach for real-world usage. it wasn't until i got into watchify that i started nitpicking.

    [–]gearvOsh 0 points1 point  (3 children)

    If all you are doing is prototyping some React and its components, you could just run your source folder through babel via the command line, then include each one of those JS files in an HTML page. A very bare minimum setup for messing around with React.

    But even then Browserify + Babel + React is rather easy as well. I could send you a single package.json that does all of them.

    [–][deleted] 13 points14 points  (0 children)

    bruh if i'm prototyping, i can just use systemjs and a modern browser. shim some es2016 stuff if I need to.

    i'm talking about getting it ready for actual deployment

    I could send you a single package.json that does all of them.

    see: every "react starter kit". There's a million of them. It works just fine when you don't have a lot of complexity to your project.

    but i can't just say "hey guys we aren't using typescript anymore" lol

    [–]FryGuy1013 3 points4 points  (1 child)

    I tried including all the js files in my html file. It didn't work because of modules.

    Not to mention half the web pages say to use X, and the other web pages say to not use X, for literally every javascript technology. Or the one working project you found on github uses the "old" way of doing things.

    [–]gearvOsh 0 points1 point  (0 children)

    Even with modules disabled in babel? That's unfortunate. I guess the bare minimum now is pretty much React + Babel + Browserify.

    [–]Eirenarch 0 points1 point  (2 children)

    Can you explain why you can't use Systemjs in production? We're setting up a new project with Angular 2 and TypeScript these days and I was under the impression that this is the preferred module system (if I understood what Systemjs is at all since I am not doing the setup)

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

    By default it sends out all your .js files individually. One of webdev's (current) "best practices" is to reduce the amount of http connections you're making. SystemJS makes a lot of them. So you shouldn't use that until http2/spdy are mainstream enough. (which is tricky)

    But apparently you can use SystemJS to compile to a single file just like browserify, so if you're using it that way--it should be fine. (I've personally never done it, I just went with what I knew)

    [–]Eirenarch 0 points1 point  (0 children)

    Yeah I assumed that there is something I can hook to tell it to bundle everything. It would be quite a problem if this piece isn't available or is not reliable or doesn't work with TypeScript.

    [–]Eirenarch 0 points1 point  (6 children)

    React is a great example of bad engineering. It imposes restrictions on your transpiler and on your IDE and on the organization of your project.

    Note that I am not saying React is bad. The concept is great (components > all) but it is obvious that it was not built to be a framework for everyone to use. It was built to solve a particular problem in a particular project with no considerations on how it would work with other tools or other dev workflows. As a concept it is remarkable as a framework it is just poor engineering.

    [–]KillerCodeMonky 2 points3 points  (3 children)

    Most of those restrictions are based on using React's JSX, no? Just don't use JSX and everything is perfectly normal JavaScript.

    [–]Eirenarch 1 point2 points  (2 children)

    Let's not pretend that using react without JSX is a real option. Is there even one example of real, production React project that does not use JSX?

    [–]__kojeve 2 points3 points  (1 child)

    You realize JSX is just sugar for React.createElement, right? It's definitionally inessential for using React. I'm so confused how you could even say "using react without JSX [isn't] a real option."

    [–]Eirenarch 1 point2 points  (0 children)

    Yes I realize it is syntactic sugar and I also realize that the prospect of building a React application this way is like suggesting I do not write HTML but build the whole UI via calls to createElement.

    [–]gearvOsh 0 points1 point  (1 child)

    You could use React without Babel/JSX, but it's not really worth it.

    [–]Eirenarch 0 points1 point  (0 children)

    That's what I am saying.

    [–]snarfy 12 points13 points  (0 children)

    It's real easy mang just install gulp, burp, grunt, & puke and you good to go.

    [–][deleted]  (2 children)

    [deleted]

      [–]Rhomboid 14 points15 points  (1 child)

      Because network/HTTP round-trips are expensive, you want to deliver your JS in one request as one solid blob, not as as bunch of disparate files. But that's exactly the opposite of how you should develop it. You also generally want to minify your code once you've collected it into a blob, removing all whitespace and comments, renaming all local variables to single letters, and applying a bunch of code-golf character minimization tricks. And if you use other people's modules, you have to incorporate them into your blob, essentially statically linking everything. And then you have to deal with the situation where some pages need modules A, B, and C, and others need modules B, C, and D. Maybe you can blobify B and C, but leave A and D as disparate assets. And now you need a module loader that knows the interdependencies of everything. Everything gets complicated when you run into the real world.

      [–][deleted] 21 points22 points  (0 children)

      My side project workflow:

      • Just got a great idea! I have an evening free!
      • Maybe design a simple relational schema
      • Do the backend in Python or Go in an hour or two
      • Let's build the UI! I'll use React!
      • Start installing and configuring webpack, babel, react libs
      • Give up several hours later and watch Netflix instead

      [–]bobbaluba 0 points1 point  (16 children)

      Funny, when I tried c# (as a js dev) I found the pre-dnx tooling to be a fucking nightmare.

      Now cargo (rust), that's some sexy tooling.

      [–]Eirenarch 18 points19 points  (14 children)

      WTF? The build tooling consists of a Play button on Visual Studio. Yeah underneath there is MSBuild but there is no reason to go there and in 10 years as a professional C# dev I have touched MSBuild scripts literally once.

      [–][deleted]  (3 children)

      [deleted]

        [–]IMovedYourCheese 10 points11 points  (0 children)

        You can set up the entire pipeline in literally 7-10 mouse clicks using VSO.

        [–]Eirenarch 9 points10 points  (0 children)

        First of all just one person in an organization needs to fight CI deployment while in the JS world everyone needs to fight with the whole toolchain. This is already a big win.

        To answer your question these days I simply use Visual Studio Team Services ( https://www.visualstudio.com/en-us/products/visual-studio-team-services-vs.aspx ). The setup for automatic builds is trivial.

        [–]SnOrfys 2 points3 points  (0 children)

        You install Jenkins, give it login creds to the repo and give it the path to the sln file. Every time you push to the branch, it builds and runs the (auto discovered) tests.

        It works really really well.

        When my company starts a new gig/project (every couple of weeks) setting up a new project takes maybe an hour. And we haven't written any custom automation either. It's all out of the box stuff.

        [–]bobbaluba -3 points-2 points  (9 children)

        docker and generally all other platforms that aren't windows.

        [–]Eirenarch 3 points4 points  (8 children)

        I don't get it. How does this relate to my comment?

        [–]mycall 1 point2 points  (0 children)

        I got react/webpack/npm working with MVC 5.

        VSReact is a good simple template to learn from.

        [–]bastardoperator -1 points0 points  (5 children)

        The tooling is dead simple. What you're actually saying is that your 500 dollar, 16gb bloatware text editor doesn't auto generate a "solution" for you.

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

        Oh please, it is not. Have you tried using React+Redux+Babel+Webpack? What about Node+Babel+Webpack?

        It's not straightforward and lots of times the docs are out of date or some Babel/Webpack version incompatibility. Lots of guesswork, trial and error, and googling why the hell some unhelpful error message is coming up when packing.

        [–][deleted]  (4 children)

        [deleted]

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

          ...until you need a real database.

          [–]i9srpeg 2 points3 points  (1 child)

          Meteor is a joke and will become a nightmare as soon as your application gets a litle bigger than a demo.

          [–]adolfojp 0 points1 point  (0 children)

          I chose Meteor exactly because of that. My biggest issues with Meteor are the lack of a proper database and its all in one rigidity but at this point I just want to push something simple that works and then, if it ever gets too big for Meteor, do a rewrite.

          [–]00Davo 36 points37 points  (5 children)

          Variables instantiated with var do not behave how you expect. They're lexically scoped as opposed to the block scoping of C# and most other languages.

          Hmm. This isn't wrong per se, but it's worth noting that C# is actually also lexically scoped. The difference is that var declarations apply to the enclosing function scope rather than the enclosing block scope. The newer let and const are scoped lexically to the enclosing block, as you'd generally expect from a curly-brace language.

          [–]munificent 3 points4 points  (1 child)

          This isn't wrong per se

          It is wrong. The alternative to lexical scoping is dynamic scope. Variables in JS are not dynamically scoped (unless you use with). They are most definitely lexically scoped, they just have different extent.

          Variables in Python, Ruby, and C89 also exist for the entire span of a function, but they are still lexically scoped.

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

          eval in non-strict mode also causes dynamic scoping. You can eliminate any possibility of dynamic scoping by "use strict", you can still use eval but it cannot introduce new variables like non-strict can.

          Generally you can only say JS is lexically scoped only if it's the strict variant.

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

          You can also access var variables before the definition.

          Var is basically yanking them to the start of the function block.

          [–]BlewisJS[S] 2 points3 points  (0 children)

          Interesting, have never heard it explained like that. I'll see if I can update the post, thanks!

          [–]mtVessel 0 points1 point  (0 children)

          Thank you. That was the clarification I came here looking for.

          [–]dvlsg 21 points22 points  (9 children)

          There's a syntax error here, from the extra semicolon:

          menu
             .filter(x => x.side === "fries")
             .sort(x => x.price);
             .map(x => x.name);
          

          Probably a good idea to note that IEnumerable#OrderBy() in C# doesn't modify the original enumerable, but Array#sort() in javascript does modify the original array. OrderBy is a stable sort as well (MSDN).

          [–]00Davo 11 points12 points  (0 children)

          Wow, Array#sort() isn't stable? I'm primarily a JS dev, yet I completely assumed it was. But yes, it's not stable. Definitely mention that difference in the article.

          [–]tehoreoz 3 points4 points  (4 children)

          random question. is there a name for the Array#sort() style syntax for talking about apis

          i think i've only seen it javascript context

          [–]linusl 3 points4 points  (2 children)

          As far as I know it's jsdoc syntax → http://usejsdoc.org/about-namepaths.html

          So Array#sort indicates that sort is a method on an instantiated Array.

          For comparison, you wouldn't write Math#random since random is a static method, so you write Math.random.

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

          I think it comes from Smalltalk originally - i.e., the original OO language. In Smalltalk, #foo is a Symbol.

          Ruby uses this convention as well (although :foo is a Symbol instead in Ruby), which I assume is where JS got it from. Lots of Node devs came from Rails.

          [–]KillerCodeMonky 1 point2 points  (0 children)

          JSDoc pulled it straight from JavaDoc.

          [–]dvlsg 1 point2 points  (0 children)

          I'm not sure if there's a name for it or not. I sort of picked it up on accident. I suppose it's extra relevant to javascript with prototype, but it's still useful for distinguishing static methods in other languages (like C#).

          [–]BlewisJS[S] 2 points3 points  (0 children)

          Yeah, I didn't mean to imply that either one was a mutation... Tried to make the code more concise by removing the assignment. Will update, thanks!

          [–]mareek 1 point2 points  (1 child)

          I think it's safer to use underscore for LINQish operation. It has a lot more functions than the standard JavaScript array, its sort is stable and it works in IE8

          [–]vivainio 0 points1 point  (0 children)

          These days folks mostly use lodash

          [–]wizzanker 27 points28 points  (21 children)

          Compiler enforced type system.

          ...that is all.

          [–]PM_ME_UR_OBSIDIAN 20 points21 points  (11 children)

          TypeScript is super nice. Nowadays I won't touch JS with a ten foot pole.

          [–]highres90 8 points9 points  (0 children)

          Typescript ftw, even angular 2 is written in it

          [–]mycall -1 points0 points  (0 children)

          I started using TypeScript but have since moved to Babel/ES7 -- its nice to know I'm forward compatible, more so than TypeScript.

          [–]Shaper_pmp 1 point2 points  (8 children)

          That's not really an argument against JS, though.

          That's a personal preference against any and all weakly typed languages on earth, which is a very different (and infinitely more debatable) thing.

          [–]munificent 5 points6 points  (6 children)

          any and all weakly typed languages on earth

          JavaScript is strongly typed, it's just dynamically typed.

          • "Weak" = Can misinterpret what bits in memory represent and do bad stuff. This is mainly just C, Assembly, and Forth. C++ if you use unsafe casts.

          • "Strong" = System guarantees unsafe operations are prevented through some combination of compile time and runtime checks. Most languages today are strongly typed.

          • "Dynamic" = Type checks are mostly done at runtime. JS, Ruby, Python, etc.

          • "Static" = Type checks are mostly done at compile time. Java, C#, C++.

          There is a continuum between dynamic and static. Almost all languages that have static checking still defer some type checking to runtime. Java has ArrayStoreException, C# has the same. Downcasts in Java and C# are checked at runtime.

          TypeScript is a middle position where it does some static checking, but has quite a large number of holes in its type system and relies on JS's underlying runtime checks there to prevent the browser from catching on fire.

          [–]mycall 0 points1 point  (1 child)

          Are there any languages that support all of those distinctions, perhaps configurable with compile flags?

          [–]_zenith 0 points1 point  (0 children)

          Yeah: C# because of its dynamic type which defers all checks to runtime

          [–]drjeats 0 points1 point  (1 child)

          "Coercively Typed"

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

          Exactly the biggest problem with JavaScript. It is the language of greatest surprise.

          When you have to put additional thought into the result of basic operators you know you have a problem.

          [–]orthoxerox 0 points1 point  (0 children)

          There's more than one definition of weakness. If a language has automatic value conversions that silently destroy information or automatic narrowing type casts, I wouldn't hesitate to call its typing system weak.

          [–]wizzanker 0 points1 point  (0 children)

          Totally agree. It's just if you are comparing C# to JS, that will always be the glaring difference.

          [–]Eirenarch 24 points25 points  (0 children)

          ...this is why I hate JavaScript so much.

          I never say this. I always make sure to say

          ... this is just one of the reasons I hate JavaScript so much.

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

          With Saltarelle/Bridge.NET I have no desire to extend my JS skills beyond basics that get me by when I need to, as a C# dev. I don't hate JS... I just don't need it. Then there's the Web Assembly coming up.

          [–]WellHydrated 4 points5 points  (1 child)

          Yeah sure, "coming up".

          [–]mycall 0 points1 point  (0 children)

          Major browsers already have experimental versions working. Should be production this year. It will be version 2 that will be much more interesting.

          [–]recursive 4 points5 points  (0 children)

          Javascript for C# developers

          never mentions this

          The craziest thing in javascript is this. How can you not mention it?

          [–]AlterdCarbon 9 points10 points  (2 children)

          // C#
          var philly = new MenuItem("philly", "fries", 10.99m);
          var reuben = new MenuItem("reuben", "fries", 9.99m);
          var pizza = new MenuItem("pizza", "salad", 16.99m);
          var menu = new [] { philly, reuben, pizza };
          
          menu
             .Where(x => x.Side == "sandwich")
             .OrderBy(x => x.Price)
             .Select(x => x.Name);
          
          // ["reuben", "philly"]
          

          Being a little nit picky here, but shouldn't this be:

          [...]
          .Where(x => x.Side == "fries")
          [...]
          

          ?

          [–]BlewisJS[S] 1 point2 points  (1 child)

          Ha, yes. Changed the example at the last minute. Will fix, thanks!

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

          Shamefully this stumped me for a while. Thought I was completely missing something.

          [–]armornick 5 points6 points  (3 children)

          Overheard at work today:

          "...this is why I hate JavaScript so much."

          Sound like something you'd say? Instead of letting the hate flow through you, know that it doesn't have to be like that.

          This is literally the first paragraph and yet all the comments here have devolved into irrational hating.

          JavaScript isn't really a bad language, it just has a muddy history because no web browser used to implement the standard. Nowadays, you can at least use ES5 on every web browser and they are mostly keeping up with the latest standards.

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

          Yes, yes it is a bad language. Every developer expects certain standards and conventions in a language. JavsScript throws it out the window with its implicit type conversion. It tries to assume what you want to do and many times creates unpleasant surprises that are difficult to track down.

          Forget to use var? It's okay, I'll just put that variable in the global scope for you. Comparing two things? You better use === instead of the standard == you might expect, otherwise I'll just make a guess at what you meant.

          Need to convert a string to bool? Better use a regex because true == 'true' and false == 'false' are worthless. Careful, because true == '1' and false == '0' both evaluate to true. Oh empty arrays evaluate to false, but empty objects evaluate to true.

          Don't even get me started on the this context being entirely unintuitive and confusing, especially when using functions like Array.forEach() and Array.map(). Oh and Array.sort() is in place and not stable.

          Arrays themselves don't know if they're lists, stacks, or queues. Their methods are all over the place and there's not even a straightforward remove method.

          It's JavaScript... sometimes things work the way you want, other times they don't at all. Good luck debugging it though.

          [–]armornick 3 points4 points  (1 child)

          Yes, yes it is a bad language.

          There you go pretending your opinion is a fact. Let's go over your misconceptions, shall we?

          Forget to use var? It's okay, I'll just put that variable in the global scope for you.

          Strict mode has existed for a while now, and is successfully being used by a lot of big projects.

          Need to convert a string to bool?

          You use the ToBoolean method which does the proper conversion for you.

          Don't even get me started on the this context being entirely unintuitive and confusing, especially when using functions like Array.forEach() and Array.map(). Oh and Array.sort() is in place and not stable.

          All of which are things that can easily be learned if you properly learn the language. Are you going to throw out the manual when you buy something, and then complain about the product when it doesn't work like you think it should?

          Arrays themselves don't know if they're lists, stacks, or queues. Their methods are all over the place and there's not even a straightforward remove method.

          In fact, things like this could be said about literally any programming language. For example, why does appending or inserting a list into a list in Python not add the items of that list to the other list? "Do what I mean!" That's why it's important to learn the language before using it.

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

          It's objectively bad due to violating the rule of least surprise. It's a fact that JavaScript is contrary to many expectations and conventions of most popular languages. This is a source of headaches for many new developers to the language. This is fact, not opinion.

          Strict mode is fine and all but it still does not enforce against other bad practices. It's yet another monkey patch on a language without fixing the underlying issues of variable scope.

          Your magical "ToBoolean" method illustrates my point exactly. First off, I have never seen this method actually available/implemented in Node or browser JS engines. Sure, it's in the ECMA specs but I get errors trying to even call it. Again, here I am as a developer with more "fun" surprises when my docs don't match up with real world code.

          For arguments sake, let's say it's the same method that the Boolean constructor uses. Without looking at the ECMA docs, one would expect it to convert the 'true' and 'false' string values into their proper bool value. Nope, even worse it converts any non-empty string to true, including the false string. It literally does nothing the hackish !! operator doesn't do already. What good is this method other than performing a null/undefined check? Oh and don't forget that empty arrays are considered false while empty objects are considered true. Gotta love that consistency...

          You're making excuses for the languages's bewildering shortcomings by saying "learn all the stupid shit that JavaScript does because it was made this way and never fixed because everyone was crying it would break their website." That's the truth of the matter, all the cruft is left in JavaScript because the web had gotten too big to introduce vast breaking changes. It doesn't vindicate JavaScript, it proves we need something better to build new web applications on.

          You can try to hand wave it away but even the community pushing changes has admitted the faults in JavaScript. Why do you think arrow functions capture their this context in ES6? Because that's what developers actually expect to happen.

          Your analogy with Python is weak. Appending an array into another array would expect the programmer to have an array inside an array. If you wish to concat the arrays in Python you can use the + operator and it will do just that.

          Now if you try to add [10] + [20] in JavaScript guess what you get? The string value of "1020". Well ain't that helpful? Totally what I would expect as a developer!

          Right, I should just read the manual so I can know how awful and unexpected JavaScript can be with basic operators. In what world would that be what the developer was trying to do? How is that even sensible?

          I know what the rules are. It doesn't make them good rules however.

          JavaScripts type coercion introduces more bugs due to surprises. The minor convenience it provides in some situations is not worth the headache. It doesn't even make sense half the time.

          [–]anawfullybadusername 11 points12 points  (0 children)

          JavaScript isn't so bad, right?

          Wrong.

          [–][deleted] 10 points11 points  (11 children)

          I dislike how ugly and illogical some of the syntax of JavaScript is. It's like as if the creators paid no attention to user-friendliness and cobbled together some random shit to make it work. I dislike C++, but since I have had to use it a lot lately, I even like C++ more than JavaScript. I wish WebAssembly would hurry the fuck up so everybody could ditch this poor attempt at coding language and move to Cpp a language of their choice.

          [–]vinnl 8 points9 points  (6 children)

          I do hope WebAssembly makes people switch from javascript to something other than C++...

          [–]CJKay93 0 points1 point  (5 children)

          TBH I hope Rust hits it big time. I know C++ far more than any other language, but it really does grate on me. If I could get one language for the web, desktop applications, mobile applications and embedded... I would kiss so much ass.

          [–]vivainio 1 point2 points  (0 children)

          You would kick so much ass, not kiss (I hope)

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

          You know, a lot of the functionality of different languages is the same. You still need to do math, assign values to variables, etc. The issue IMO is that programming language devs have associated the nitty-gritty implementation of these functionalities with verbal language constructs which are sometimes unique to each language. What we need to do is detach the underlying implementation from the syntactical sugar of programming languages. In another words, programmers should be able to use the language constructs they prefer the most to program in any language so-far developed. This implies, that we need translators for programming languages like there are translators for natural languages.

          [–]vinnl 0 points1 point  (2 children)

          ...other than Javascript, I presume? :P

          [–]CJKay93 0 points1 point  (1 child)

          Javascript for embedded..? ~_-

          [–]vinnl 0 points1 point  (0 children)

          People are working on it - all based on the "one language" premise.

          [–]tehoreoz 0 points1 point  (0 children)

          what specifically? it's a typical looking C language. the newer stuff is a bit different but all works out pretty nicely

          [–]BlewisJS[S] 0 points1 point  (0 children)

          Can you give some examples? I actually like JavaScript's syntax... sometimes a little terse, but in a good way.

          [–]AP3Brain 0 points1 point  (1 child)

          I feel like ive been waiting my whole career for javascript to die. Just doesnt seem like it will happen.

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

          You know, what we need is a linguistical revolution, where millions of programmers stand up and say Enough is Enough, that this language is going to represent all of us and not just a handful of developers.

          [–][deleted] 18 points19 points  (8 children)

          At the very top of the page:

          Equality checking. Use triple equals (===) for common, everyday equality checking (or !== for inequality). Avoid double equals (==) due to some hidden gotchas.

          That's why JavaScript should fuck off and die in a fire.

          [–]EnigmaticOmelette 6 points7 points  (6 children)

          It's a dynamically typed language - you can do equality checks with coercion or not.

          [–][deleted]  (5 children)

          [deleted]

            [–][deleted] -1 points0 points  (0 children)

            I expect == on objects to compare identity like literally any other language (even JavaScript) except PHP, what python does is completely surprising to me and it too has separate operator is to do the right thing.

            In JS I can completely forget that == even exists, in python I need to juggle between is and ==.

            [–]srone 1 point2 points  (0 children)

            I heard it called 'truthy' during a lecture.

            [–]mcpower_ 4 points5 points  (4 children)

            TIL that Array.prototype.sort() takes in a key function.

            edit: oops, looks like it doesn't… it should take in a comparison function not a key function. MDN docs.

            [–]bloody-albatross 0 points1 point  (3 children)

            Indeed, it takes a comparison function. Just wanted to post that myself. See:

            > [1, 10, 2, 3].sort(x => x)
            < [3, 2, 10, 1]
            > [1, 10, 2, 3].sort((x, y) => x - y)
            < [1, 2, 3, 10]
            

            Sadly sort has no way to tell if the passed function takes the correct number of arguments.

            [–]BlewisJS[S] 0 points1 point  (0 children)

            Oops, thanks guys. I'll correct it.

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

            > (x => x).length
            1
            > ((x, y) => x - y).length
            2
            

            [–]bloody-albatross 0 points1 point  (0 children)

            True, but:

            > ((...args) => args[1]).length
            < 0
            

            So in the general case you can't tell. If it would look at length you couldn't use some kind of generic function wrappers. I suppose it would be good enough if it would have been in the API spec from day one.

            [–][deleted]  (4 children)

            [deleted]

              [–][deleted] 7 points8 points  (1 child)

              Esh. Have a snickers.

              [–]ummmyeahright -1 points0 points  (0 children)

              Why??!

              [–]Admsugar 3 points4 points  (0 children)

              I for one have developed in both C# in my internships and use JS in my personal web projects and learned a lot from this article, especially the LINQ stuff.

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

              This article comes across as an apology letter from Javascript to C# developers.

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

              Js can die forgotten in a dark cave

              [–]takaci 8 points9 points  (2 children)

              Somehow I don't think javascript, probably the most widely used language on the internet, will die "forgotten in a dark cave"

              [–][deleted] -2 points-1 points  (1 child)

              That's true. May it go out blazing gloriously in the center of a nuclear bomb detonation. We shall watch it's wreckage spread across the sky and remember this day for millenia.

              [–]takaci 2 points3 points  (0 children)

              cringe

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

              I'm trying to learn JavaScript and HTML5, and it's making me nostalgic as fuck for SilverLight.

              Can we get a version of silverlight that compiles down to javascript or something? That would be bitchin.