I tried JS multiple times. And every time, easy things are complicated when doing them in JS. It is much easier and faster for me to do those same things in C, even though I'm equally familiar with both. This is mostly because there are just so many gotchas.
Here are some examples from this week:
Checking whether a passed argument is an array or a dict:
var a = []
if (Object.prototype.toString.call(a) !== '[object Array]') ...
If you import a library, they could have modified the global scope. This is common in JS libraries. Then some things you wrote don't work.
undefined/null thing
differences between var declared function and regular named function.
Many things in the language are not obvious and you have to discover them through trial and error or study JS internals and find out how things are implemented.
As someone that wrote C/C++ for decades I hated JS. Now that I've gotten used to JS every time I'm forced to go back to C/C++ I hate Hate HATE IT.
Things that take 5 lines in JS take 200 in C++ all to make the type system happy. Yes I understand the trade offs. Wrote games most of my career. I used to find it cool that I could write a 400 line templated intrusive list class that generates just 1 instruction on use. Yippee. Now though I just resent the fact that have to write giant implementations like that for code who's performance doesn't matter.
In JS forgot a little piece of data? It's generally almost zero lines to hack it in. C++? It's often refactoring hundreds of lines of code.
Wanna to wrap some function to monitor it, test, sanitize, .. trivial in JS. Next to impossible without massive refactoring in C++
When I have to do C++ again I will but it won't be without kicking and screaming.
> Checking whether a passed argument is an array or a dict
Luckily solved in ES2015:
Array.isArray(thing)
The toString trick is pretty outdated, in ES5 you can also do:
thing instanceof Array
> (perhaps not js itself, but how it is used) Leaking DOM nodes are a thing
Definitely not JS itself, it's easy to create circular references between JS objects and DOM elements. It's just the way the DOM is (poorly) designed and the way it interacts with JS.
> for each (var myVar in myObject)
That's not even standard, just a Mozilla "dialect". I don't think that's supported by any engines other than SpiderMonkey and predecessors.
>The toString trick is pretty outdated, in ES5 you can also do:
> thing instanceof Array
instanceof is ES3.
> That's not even standard, just a Mozilla "dialect". I don't think that's supported by any engines other than SpiderMonkey and predecessors.
To quote MDC:
> The for each...in statement is deprecated as the part of ECMA-357 (E4X) standard. E4X support has been removed, but for each...in will not be disabled and removed because of backward compatibility considerations. Consider using for...of instead. (Please refer to bug 791343.)
for each (...) -> It's not supported anywhere, so forget it.
for (var x in a) -> x is the key, so it's kind of inconvenient. You have to watch out for inherited properties/methods so one should check for a.hasOwnProperty(x).
for (var x of a) -> It has mostly no gotchas. Only poor browser support.
.forEach only works with arrays and from ES5 on. You have the good old "this"/scope gotcha.
if (a instanceof Array) ...
// or polyfill
Array.isArray = Array.isArray || function(a) {
return a instanceof Array;
};
Object.keys can be cleanly shimmed without braking older browsers. You can always shim in the behavior you want, as long as you don't need IE7 support.
console.log("I lose and lose again, not even close.".replace(/\blose\b/g, "win"));
If you're using ES6 or node-style modules, you shouldn't generally mess with global state, unless you are polyfilling new features. Promises (bluebird), fetch, etc...
Understanding falsy values is a core part of learning JS, as is coercion... no it isn't perfect, but there are flaws in any language you can bring up.
As to a function assigned to a variable vs a function declaration, well again that's part of learning the language.... Being able to use functions as first class expressions is a very powerful feature, that frankly works pretty well.
Of the features missing from JS proper, an isolated invokable web-workers scenario with plain, side effect free functions/modules would be a great start (not the current way via secondary script).
That said, most of your complaints are things that are easier to work around, or simply things that you learn with the language. It's not that different from learning warts in Python (which is better than many), C#, Java or anything else.
See `Array.isArray` which you can polyfill however you like ... Beyond that, if you bring primitives from another frame, you kind of get what you deserve. Most likely you should check for not a string, but has `length` property that is a Number and use `Array.from` with your conditions, especially with arguments or dom collections.
Most likely when working across frames, you should use messaging, unless you're doing something truly hokey... In either case, working across frames like that is akin to poking into the memory of one process from another. It's bound to have issues...
I don't think this is something that WebAssembly would allow you to do in the first place...
The library is ramdajs.com and it can be grabbed from npm.
I do not agree that everything should be handled with standard libraries. It's better for these things to be modular and versioned, instead of them being pulled from a big bloated standard library.
The code clearly does what was being asked in a very simple and non-broken way.
Perhaps the issue here is that non-JavaScript engineers are used to kitchensink standard libraries and avoid mixing and matching to get the best experience the ecosystem offers.
You're building a straw-man there. A standard library can certainly be made to be modular and versioned. It doesn't have to be bloated for any reason whatsoever. This is Javascript - you can chop up your scripts however you want.
The problem with mixing and matching libs is that no two JS devs do it the same. Some will even re-build the same lib that has already been built by hundreds of JS devs because NIH.
Here are some examples from this week:
Checking whether a passed argument is an array or a dict:
(perhaps not js itself, but how it is used) Leaking DOM nodes are a thing: https://developer.chrome.com/devtools/docs/heap-profiling-do...Easy things like getting values of a dictionary:
});in Python, it's just .values()
Errors aren't thrown when there are obvious issues with the code.
String.replace replaces one instance instead of all instances in a string.
Functions arguments are a bit of a mess.
differences between
random things like these:http://stackoverflow.com/questions/2568966/how-do-i-pass-the...
All the things here:
http://www.toptal.com/javascript/10-most-common-javascript-m...
If you import a library, they could have modified the global scope. This is common in JS libraries. Then some things you wrote don't work.
undefined/null thing
differences between var declared function and regular named function.
Many things in the language are not obvious and you have to discover them through trial and error or study JS internals and find out how things are implemented.