And the funny thing is they are teaching all these at bootcamps and the students have a hard time trying to understand the concepts with so many variations in them.
There is however light at the end of the tunnel which I think where TypeScript is.
Some variant of this is the top-voted comment of every HN thread on modern JavaScript.
> For example, the promises API, now we also have async/await. The module system, with require(s), then import/export, and there's browser JS and system JS (node), and npm and now yarn, then your build system, with webpacker, browserify, bower.
Async/Await are essentially sugar on top of Promises -- use them if you want, you don't have to. Require has been deprecated in favor of import/export to be more semantically meaningfull (e.g. with TypeScript). Webpack is the next iteration of the Browserify approach, and Bower is just flat out dead.
All of this happened 3-4 years ago, if it's your job it's not hard to keep up. If it isn't your job there's plenty of guides out there to get you up to speed. I wouldn't expect to be able to jump back into Android dev after 5+ years away from it without doing some reading, I don't know why people expect web development to be so static.
The thing is that the JavaScript language is so aggressively changed, unlike Ruby for example, that for years, working with it professionally, the only change I can remember that was significant in my work was the safe navigation operator `&.`. The build tool (Bundler) is still the same, along with other tools. Not sure why JavaScript can't do the same? More innovation I guess?
I don't have the actual transcript so summarizing based off of someone else's comments:
* I added promises to Node in June 2009 but foolishly removed them in February 2010. * Promises are the necessary abstraction for async/await. * It's possible unified usage of promises in Node would have sped the delivery of the eventual standardization and async/await. * Today Node's many async APIs are aging badly due to this.
Having said that, looking at the code sample it's looking quite nice (ignoring the #'s).
It being a superset with TypeScript-only features on top of ECMAScript, wouldn't the "aggressive changes" you complain about be worse?
I can understand the frustration of people who don’t touch JavaScript on a daily basis, or confusion of newcomers. I can sympathize. But I don’t think that personal inexperience should reflect negatively on the language.
Async/await and promises do seem to be a thorough solution, with my main criticism being that they are difficult to conceptualize what is going on when a lot of promises are being composed together.
As a beginner it's a far more daunting picture, compared to Rails for example, but as a practitioner I'd like to build my project with pieces suited for purpose.
Basically everything on stackoverflow/github issues/random JS blog is outdated regarding the inevitable error messages youll google
Every project has its own little tech stack, each part being filled a-la-carte by some JS framework/library/preprocessor. The server might use express or raw node or Koa, the web client might use React or Angular, styles might be done with SCSS or styled-components, etc. JavaScript might have a different syntax between projects if they're using typescript/babel. There are lots of choices to fit many needs and preferences, and that's a good thing™.
All of these technologies are built around the same language and syntax, which at its core is relatively simple to learn (aside from the occasional type coercion/prototypal inheritance weirdness). This makes learning new frameworks and tooling easy: does it need a config file? Chances are it's a raw .js or .json file with a similar format to webpack.config.js or package.json or .eslintrc.
It's not a huge ask, nor would it be terribly difficult, for one developer to become competent with both Angular and React, for example. And once you've made your choices for your project and installed all the npm packages you need, there's no need to keep all of them updated to the very latest, bleeding-edge releases at all times. Just install patch (0.0.x) updates and wait for npm to warn you about any security issues in your existing packages.
That's why I'm kind of surprised to see so many companies advertising JS jobs with requirements like "Must have 3 years experience with React." Any competent Angular developer should be able to pick up React and start being useful in a matter of weeks, not months or years. Just hire JavaScript Developers, IMO.
These go together, right? An async function returns a Promise, await operates on a Promise.
@downvoters: do you care to add a reply? it’s silly that instead of having a conversation, we’re doing this.
Yes, the all-too-common super-deep dependency trees are a problem. If you're reasonable about your dependencies though it doesn't happen (my last few JS dependency graphs are pretty similar to my Python ones).
One of the issues is the stdlib and the other issue is a different mindset due to a lower barrier of entry to creating a package. (eg. creating and maintaining a package in Python sucks, so you're less likely to do it for small, self-contained things rather than create a utils.py)
shrugs, I honestly don't know what meaningful change this discussion can lead to. People are generally aware of this, and the problem isn't actively getting worse, so I imagine it'll get better over time.
If fields in class definitions are incorporated I would like it to simultaneously make the field names in scope for any methods within the class definition.
class Fish extends Vertebrate {
color = "blue";
constructor (speed) {
super();
this.speed = speed;
if (speed > 5) color = "red" // does not need this.color because color is a class field.
}
}
Fish.prototype.setColor = function (newValue) {
this.color = newValue; // this. is required because this function is outside the class definition.
}
Adding this feature would allow for much tidier method bodies since there is now enough information to imply this.fieldName from fieldName alone. class fish {
color = "blue"; // color is now a name in scope for this class definition
#agenda = "Total World Domination" // agenda is now a name in scope for this class definition
...
reveal () {
console.log("I am a "
+ color + " Fish " // interpreted as this.color
+"seeking " + agenda // interpreted as this.#agenda;
}
}
You can still have this.agenda for public addon fields. But for the private one you can refer to it within the class definition without either this. or #Then what happens in 2 years when the "next big thing" comes out that is mind-boggling-ly awesome and obviously obsoletes TypeScript? The latest addition to JavaScript is Array.flat... it should be called Array.flatten, but there was a popular third-party library 15 years ago that used it and you can't go breaking the web every time there's a new "best way" to do things.
Each fan of each language will happily tell you why theirs is better than any others, and why it's the obvious choice to be the default in a browser. Everyone might agree they don't want JavaScript, but no one will ever agree on what should replace it. That's why your two options will only ever be "JavaScript" or "transformed/WebAssembly-fied other language".
I'd honestly rather have browser support less than more and I'm happy with type annotations remaining a language superset. The current typescript situation is actually fantastic and as a python dev, I envy it a lot.
Probably the largest problem I have with modern projects is how unfriendly they are to experiment with on the page, even if there's no intention to prevent it.
Typescript can't supplant javascript or relegate it to a legacy language... because typescript doesn't compile to bytecode or machine language, but to javascript. Browsers that support typescript natively must by definition also support javascript natively, and the more of the former you have, the more of the latter you have.
So make it look full on like traditional OOP with classes, I guess? I suppose the prototype folks lost this debate.
#this_is_not_a_comment = 6;For example, what does `this.foo` access in an object? the private property `foo`? the public property `foo`? What about if I'm using your object and put a new property `foo` on it after it's created, then what happens?
None of the answers to those questions are really good. If the private shadows the public, then how do you access the public? If it's the other way around, then external users can break your private fields by adding a public of the same name, which kind of defeats the purpose...
TypeScript can get away with it because it's not really enforced by the runtime, only the typechecker, so their `private` isn't really private outside of TypeScript.
[1] https://github.com/tc39/proposal-class-fields/blob/master/PR...
[].concat(...arrayOfArrays)
It is also the basis more generally for the list monad, where `.flat()` is the `join` operation and `.flatMap()` is the equivalent `bind` operation.So, like, the simplest example is if you're just getting a bunch of results from a paginated source -- you want to flatten them, and it is really nice to just have a method for that.
The list monad case is more interesting because it gives a syntax for list comprehensions:
[ x + y for x in list1 for y in list2 if x % 2 == 0 and y % 2 == 1 ]
becomes list1.flatMap(x =>
x % 2 !== 0 ? [] : list2.flatMap(y => (y % 2 == 0 ? [] : x + y))
);
And more theoretically this list monad is all about composing nondeterminism, where one input could produce any of N outputs: if you store all of the current possibilities as an array then flatMap is the core composition primitive.Having become proficient with Node/Express/Sequelize at Fullstack Academy and then used them for several months, I really miss Django and Django REST Framework. The ORM, serializers, effortless filtering and permissions, etc. are--with all due respect--simply unmatched in JS-Land.
As for the front-end, I learned and used Ember for over a year before picking up React (it was "cooler" and there were more jobs). So many decisions I've agonized over with React/Redux were solved years ago with Ember. But the problem with Ember is its proprietary object system and its lack of momentum.
If I have a choice, I will be starting new projects with Django on the server-side, and Ember only when an SPA is necessary. In the past, I hesitated to use Django for templates, but the lack of a robust client-side ORM has made that option more attractive.
I don't find the answer to this [1] to be particularly compelling. This actually seems like the right solution to me.
[1] https://github.com/tc39/proposal-class-fields/blob/master/PR...
I wonder whats the reasonig behind it? `private` is already a reserved word in JS, why not just use it? https://www.w3schools.com/js/js_reserved.asp
I was against it at first, but after reading through that document, i'm on their side now. It'll be a small but useful addition in some situations, and it's scope is extremely limited.
https://github.com/tc39/proposal-class-fields/blob/master/PR...
> this is already a source of enough confusion in JS; we'd prefer not to make it worse
> Property access semantics are already complicated, and we don't want to slow down every property access just to add this feature.
> [private x] in JavaScript this would silently create or access a public field
Pardon me, but # as a declaration method of privates is an abomination.
I would've preferred the "this.private.fieldname" instead but # is what ended up winning.
At this point, it looks like they might as well import the Java syntax and call it "JavaScript fusion" and be done with it.
The prime example of javascript unnecessary bloat is fetch api which is mere wrapper for ajax calls, was developed a while ago but still cannot be used because of lack of support in older runtimes.
Its worse to forever live with two implementations(native and polyfill) and as large bundles, double the troubleshooting effort and extra support.
I do believe your concerns are still real ones, however. Fortunately, we can poly-fill.