What's wrong with JavaScript(rdallasgray.github.io)
rdallasgray.github.io
What's wrong with JavaScript
http://rdallasgray.github.io/blog/2013/06/09/whats-wrong-with-javascript/
13 comments
No method_missing please. The lack of it is one of the things I appreciate about JavaScript in contrast to Ruby. It's used similar to macros, but it tends to be used by those who forget that the first rule of macros is Don't Write Macros.
But the second rule of macros is "they are very powerful", DO write them for the cases that need it.
Anyway, method_missing is not at all the same as macros. At least in Objective C that I know it's equivalent, it's very useful.
Anyway, method_missing is not at all the same as macros. At least in Objective C that I know it's equivalent, it's very useful.
Just remember to add Weak Reference support too. This is really the only missing feature that I want in JS.
I politely submit that what you actually want is Python, Ruby, or Lua in the browser.
Well, warts aside I came to like Javascript.
And by keeping to Javascript, only better and fixed, it would be easier to reuse and adapt huge parts of the browser ecosystem and toolchain.
Ruby maybe. Lua lacks proper unicode support. Python, I've used since 1998, but can't stand the lack of proper closures (and/or how the syntax makes them awkward) for web work.
And there's two more issues with all of them:
1) they are dog slow compared to modern JS JITs like V8 (and alternative implementations like PyPy are not as mature).
2) on the browsers, due to the sandbox and other issues, you can't use most of their libraries, that use native extensions and such, so you just get their syntax, not their batteries.
And by keeping to Javascript, only better and fixed, it would be easier to reuse and adapt huge parts of the browser ecosystem and toolchain.
Ruby maybe. Lua lacks proper unicode support. Python, I've used since 1998, but can't stand the lack of proper closures (and/or how the syntax makes them awkward) for web work.
And there's two more issues with all of them:
1) they are dog slow compared to modern JS JITs like V8 (and alternative implementations like PyPy are not as mature).
2) on the browsers, due to the sandbox and other issues, you can't use most of their libraries, that use native extensions and such, so you just get their syntax, not their batteries.
Haven't we had python in the browser for a while now with pythonwebkit, pywebkitgtk, and the other webkit-native-DOM python bindings?
Do those work if you want cross-browser compatibility for users who don't have certain plugins?
I'm thinking technologies like Skulpt or Pyjamas, that let you use Python in JS, are better. It's been a while since I investigated this situation, does anyone know of other players?
I'm thinking technologies like Skulpt or Pyjamas, that let you use Python in JS, are better. It's been a while since I investigated this situation, does anyone know of other players?
The other way around; Firefox nightlies let you use Python to script the DOM directly.
"What's wrong with JavaScript" and just a single block of JavaScript was found in that post. The rest, CoffeeScript.
I agree with click event (and others) are real pain. But absence of _missing is more personal preference. Major problem of javascript it the time that it takes to implement new features into the language that can sometimes converge to infinity.
Also I would be grateful if articles about javascript would feature javascript instead of CoffeeScript.
Also I would be grateful if articles about javascript would feature javascript instead of CoffeeScript.
Dart fixes all of JavaScript's "WAT" quirks. There is proper lexical scoping, a lexically scoped `this`, no type coercion, no monkey-patching, and so forth. It also has a "method_missing" thing called "noSuchMethod".
But most importantly: It scales.
Structure is declared and not imperatively constructed. Your tools can tell what's going on without actually running the code.
But most importantly: It scales.
Structure is declared and not imperatively constructed. Your tools can tell what's going on without actually running the code.
This post is not javascript, it is coffeescript. Stop confusing the two.
From Coffeescript's website: The golden rule of CoffeeScript is: "It's just JavaScript". There was nothing at all coffeescript specific about his examples, other than the syntax. The issues he pointed out were javascript issues discussed using coffeescript syntax.
He could have, and should have, used JavaScript for those examples. Otherwise it's needlessly confusing. Not every JavaScript developer knows CoffeeScript. What possible benefit could there be in using CoffeeScript instead of JavaScript in an article about JavaScript?
Also, I feel like the misunderstandings he posted are somewhat from the perspective of Ruby developers who learned CoffeeScript and not JavaScript. Which I do fall under, but I guess I quickly picked up the quirks in the language which CoffeeScript does make nicer. I guess things like `this` are a problem regardless of how you spell it but I think someone who learned JavaScript properly would learn about the scope rules directly rather than just assuming "it works like Ruby" and then being angry when it doesn't.
Ah, that explains a lot. It certainly explains why the complaints didn't resonate with me. I know JavaScript very well, and there are things I don't like about it, but these weren't them. Or if they were, I've gotten used to them.
I think I did miss the point with my previous comment. Maybe I was confused by the title: The article isn't "What's wrong with JavaScript", but as you said it's much more about things that will confuse Rubyists who arrive at JavaScript by way of CoffeeScript.
For an article on that topic, it does make sense to have CoffeeScript examples. But it would be much better - and so easy - to include the matching JavaScript for each of the CoffeeScript files. Not only would it help JavaScript programmers understand the article, but it would show how CoffeeScript attempts to work around these issues.
Even better would be to add matching examples of similar Ruby code. Code examples in all three languages would make for an interesting article: the Ruby way, the CoffeeScript way that makes JavaScript a bit more like Ruby, and the JavaScript way.
I think I did miss the point with my previous comment. Maybe I was confused by the title: The article isn't "What's wrong with JavaScript", but as you said it's much more about things that will confuse Rubyists who arrive at JavaScript by way of CoffeeScript.
For an article on that topic, it does make sense to have CoffeeScript examples. But it would be much better - and so easy - to include the matching JavaScript for each of the CoffeeScript files. Not only would it help JavaScript programmers understand the article, but it would show how CoffeeScript attempts to work around these issues.
Even better would be to add matching examples of similar Ruby code. Code examples in all three languages would make for an interesting article: the Ruby way, the CoffeeScript way that makes JavaScript a bit more like Ruby, and the JavaScript way.
Just because it's printed on the internet doesn't make it true.
Just because you say something doesn't make it true :)
> the scoping is wacky (and the var trap is a disaster);
Read http://bonsaiden.github.io/JavaScript-Garden/#function.scope..., be enlightened
Read http://bonsaiden.github.io/JavaScript-Garden/#function.scope..., be enlightened
Knowing what's going on doesn't change that it's all still unnecessarily very broken.
Nice! Just bookmarked that.
I love javascript! The main thing: offloading the computing directly to the end user.
The best cocktail...mix some JS with some CSS3, maybe throw a little HTML5 in there....yup, the only thing I find bad about JS is bad memory management, but that (like most times), comes down to code structuring.
I love javascript! The main thing: offloading the computing directly to the end user.
The best cocktail...mix some JS with some CSS3, maybe throw a little HTML5 in there....yup, the only thing I find bad about JS is bad memory management, but that (like most times), comes down to code structuring.
It bugs me an unreasonable amount when articles that have the space to explain it properly talk about hoisting as if it's an actual step compilers do rather than just a handy metaphore. They've literally _just_ talked about scope chains. It makes it seem like a crazy ill-conceived feature rather than the result of some tricky trade-offs.
And yet nobody seems to be interested in Dart.
Dart isn't hugely popular because it's targeting Java developers and early-adopter web developer types more often come from a background in dynamic languages. And they don't like Eclipse. Dart will be successful when it is necessary for all enterprises to do front-end coding where the tools make up for some of the lower skills.
Dart VM will never be in IE , Firefox or Safari. What's the point of Dart ? to compile down to javascript? if i had to work with an alternative to JS i would chose haxe instead of Dart , since it is compatible with some parts of javascript and one can use the DOM api directly. Dart is great in theory but has little future.
> Dart VM will never be in IE , Firefox or Safari.
Same deal with CoffeeScript or TypeScript. But that shouldn't stop anyone since you can just compile to JavaScript. Minifying Dart and compiling Dart to JavaScript is almost the same thing. In both cases it's a single line which calls the compiler. If you already doing one of those things, adding the other one to your build script won't hurt one bit.
You can also use the Dart executable like Node. You can use it to write command line applications or web servers.
You can also embed the VM into other applications. Like V8, the VM itself is just a library.
There will be also a Dart VM for ARM CPUs a bit later this year.
> i would chose haxe instead of Dart , since it is compatible with some parts of javascript and one can use the DOM api directly
You can also interact with JS stuff if you use Dart. DOM stuff is done via 'dart:html', which provides a very idiomatic API. For example, all list-like things are actual Lists, which is very convenient. It's similar to jQuery, I'd say.
> Dart is great in theory but has little future.
It's great in practice, too. If you don't care about IE8, that is.
Also, Google is committed to Dart. They are also already using it for a bunch of new projects.
Same deal with CoffeeScript or TypeScript. But that shouldn't stop anyone since you can just compile to JavaScript. Minifying Dart and compiling Dart to JavaScript is almost the same thing. In both cases it's a single line which calls the compiler. If you already doing one of those things, adding the other one to your build script won't hurt one bit.
You can also use the Dart executable like Node. You can use it to write command line applications or web servers.
You can also embed the VM into other applications. Like V8, the VM itself is just a library.
There will be also a Dart VM for ARM CPUs a bit later this year.
> i would chose haxe instead of Dart , since it is compatible with some parts of javascript and one can use the DOM api directly
You can also interact with JS stuff if you use Dart. DOM stuff is done via 'dart:html', which provides a very idiomatic API. For example, all list-like things are actual Lists, which is very convenient. It's similar to jQuery, I'd say.
> Dart is great in theory but has little future.
It's great in practice, too. If you don't care about IE8, that is.
Also, Google is committed to Dart. They are also already using it for a bunch of new projects.
Disclaimer: I work on Dart.
Yes, the point of Dart is to compile to JavaScript. That's the point of any alternative language that wants to run in today's browsers.
People are still mistaken that Dart's only road to success is via all browsers adopting the VM. Dart will be just fine even if no browser, including Chrome, uses the VM. The VM in Dartium already provides for a great developer experience, and the standalone VM means it has a great server and command-line platform, and unit-testing story. Dart will be even better off if/as browsers, mobile OSes, cloud hosting providers, etc. support it.
Yes, the point of Dart is to compile to JavaScript. That's the point of any alternative language that wants to run in today's browsers.
People are still mistaken that Dart's only road to success is via all browsers adopting the VM. Dart will be just fine even if no browser, including Chrome, uses the VM. The VM in Dartium already provides for a great developer experience, and the standalone VM means it has a great server and command-line platform, and unit-testing story. Dart will be even better off if/as browsers, mobile OSes, cloud hosting providers, etc. support it.
Most of Javascript feels like a kludge and my keyboard's 'T','H','I','S' keys need to be replaced every week or two. I always ponder, what if instead of JavaScript we had Java?
Java would be even worse. Javascript is full of warts but at least you have lexically scoped functions and anonymous object literals instead of tons of named classes for everything.
I just checked my small project, and it has 111 this. and about 300 lines with plentiful whitespace. This made me think how much better would it be if it used just single dot for referencing this. Like .property
I don't know if you've toyed around with CoffeeScript before, but that's something it adds in (you can use the Ruby-esque '@property' instead of 'this.property')
I had, but I abandoned it for reasons I cannot recall right now. Maybe because I like to go bare metal every time possible. But maybe I should give it a try...
I'd definitely recommend giving it another try. I'm generally very skeptical about adding another layer of abstraction into my toolchain, but I've found the benefits far outweigh the cost. Syntactic sugar like '@' aside, I've found that working in CoffeeScript enables me to write code that's far clearer and more expressive than when I'm working in vanilla JS.
http://js2coffee.org/ has really helped me in making the transition.
Oops, I think the author meant to have copy[key] = val for the last line of this example:
The point stands though.
copyObject: (inputObject) ->
copy = []
for key, val of inputObject
copy.key = val
As written, it uselessly sets a bunch of values to the key property in turn.The point stands though.
Rename to "what's wrong with coffeescript" and this blog post might approach accuracy.
">thing: ->
> @_thing ?= new Thing
..is … irritating."
So... having one sigil to distinguish a class variable isn't irritating, but another for a variable accessed by an accessor method is. Got it.
> It’s tempting to presume that this is a ‘feature’ of prototypal inheritance
Why would this be tempting? As the author points out, there are prototype-based languages that avoid it, and you could remove prototypes from JavaScript and still encounter the issue.
> we’re not writing Java. We’re in a highly dynamic language. We want nice things. Or, we could create setters and getters using the new ES5 syntax – but that’s not available everywhere (pre-IE9, for instance), and, I would argue, is too unwieldy to apply as a rule.
You want an easy way to create accessors? OK:
I'm more sympathetic to this criticism. There's times when the fact that everything can have arbitrary properties is convenient, but it does place some burden on the developer to pay attention.
Then again, I think that's a general charge to which any highly dynamic language is going to have to answer on some point or another. And if you're prone to typing `[]` when you mean `{}` (understandable if you've come from a language where they have different meanings), it's possible you should do the more conspicuous thing and use `new Array` and `new Object` instead.
> Nothing is an object
No. What the author is really talking about that by default, there aren't "methods" with class-bound scope. Just functions whose `this` scope is dynamic but does live by some pretty understandable rules.
> _missing
Missing method's sometimes convenient, and there are occasions when I miss it in JS too, but it's much rarer than I once would have thought. Use cases in languages where functions are less often let out on their own tend to get taken care of differently in languages where they do.
> I’ve yet to hear anyone convincingly argue that JavaScript’s version of OOP offers anything in addition to or distinction from more traditional versions;
"convincingly"
Convincing who?
..is … irritating."
So... having one sigil to distinguish a class variable isn't irritating, but another for a variable accessed by an accessor method is. Got it.
> It’s tempting to presume that this is a ‘feature’ of prototypal inheritance
Why would this be tempting? As the author points out, there are prototype-based languages that avoid it, and you could remove prototypes from JavaScript and still encounter the issue.
> we’re not writing Java. We’re in a highly dynamic language. We want nice things. Or, we could create setters and getters using the new ES5 syntax – but that’s not available everywhere (pre-IE9, for instance), and, I would argue, is too unwieldy to apply as a rule.
You want an easy way to create accessors? OK:
function prop(name,gNs) {
function undef(v) { return typeof v == 'undefined'; }
var _name = '_' + name, get = gNs && gNs.get, set = gNs && gNs.set;
if(get && set) return function (x) {
return undef(x) ? get.call(this,this[_name]) : (this[_name] = set.call(this,x), this);
}
if(get && !set) return function (x) {
return undef(x) ? get.call(this,this[_name]) : (this[_name] = x, this);
}
if(!get && set) return function (x) {
return undef(x) ? this[_name] : (this[_name] = set.call(this,x), this);
}
return function (x) {
return undef(x) ? this[_name] : (this[_name] = x, this);
}
}
You're welcome. Use it like so: obj = {
thing: prop('thing')
}
when you want your accessors to do something other than getting/setting: obj = {
thing: prop('thing', {
get: function () { return foobarled(this._thing); },
set: function (x) { this._thing = unfoobarled(x); }
})
}
> What we’re really saying is ‘everything is a hashtable’. Is that a good thing?I'm more sympathetic to this criticism. There's times when the fact that everything can have arbitrary properties is convenient, but it does place some burden on the developer to pay attention.
Then again, I think that's a general charge to which any highly dynamic language is going to have to answer on some point or another. And if you're prone to typing `[]` when you mean `{}` (understandable if you've come from a language where they have different meanings), it's possible you should do the more conspicuous thing and use `new Array` and `new Object` instead.
> Nothing is an object
No. What the author is really talking about that by default, there aren't "methods" with class-bound scope. Just functions whose `this` scope is dynamic but does live by some pretty understandable rules.
> _missing
Missing method's sometimes convenient, and there are occasions when I miss it in JS too, but it's much rarer than I once would have thought. Use cases in languages where functions are less often let out on their own tend to get taken care of differently in languages where they do.
> I’ve yet to hear anyone convincingly argue that JavaScript’s version of OOP offers anything in addition to or distinction from more traditional versions;
"convincingly"
Convincing who?
>So... having one sigil to distinguish a class variable isn't irritating, but another for a variable accessed by an accessor method is. Got it.
I'm not sure you did (get it).
One is part of the language's syntax. The other is an ad-hoc convention you have to remember and check for.
>You're welcome. Use it like so: obj = { thing: prop('thing') } when you want your accessors
My eyes. The goggles, they do nothing!
>(I’ve yet to hear anyone convincingly argue that JavaScript’s version of OOP offers anything in addition to or distinction from more traditional versions; "convincingly" Convincing who?*
The author. Isn't it obvious? Also me. So make us two.
And presumably ALL the other people that write frameworks and workarounds to get traditional OOP style in Javascript.
I'm not sure you did (get it).
One is part of the language's syntax. The other is an ad-hoc convention you have to remember and check for.
>You're welcome. Use it like so: obj = { thing: prop('thing') } when you want your accessors
My eyes. The goggles, they do nothing!
>(I’ve yet to hear anyone convincingly argue that JavaScript’s version of OOP offers anything in addition to or distinction from more traditional versions; "convincingly" Convincing who?*
The author. Isn't it obvious? Also me. So make us two.
And presumably ALL the other people that write frameworks and workarounds to get traditional OOP style in Javascript.
Such a JS would enable them to reuse large parts (or the entirety) of the current interpreters/JITs, just as well as the next ECMAScript, but would also fix most BS and enable further performance improvements.
That is, what I propose, would be a slightly incompatible release, say: "JavascriptFixed".
As for backwards-compatibility, this would be played out in two ways. Transpilers (like Coffescript) could convert "JavascriptFixed" to Javascript, and people could use the script tag to denote the presence of "JavascriptFixed".
Given vendor support, the familiar syntax, and the performance improvements, it could take over JS in 4-5 years. No we'll have decade or more until the whole mess that's the next version becomes popular, and we'll still have the whole JS mess, just swept under the carpet.