top | item 8873225

Is JavaScript getting worse?

104 points| caisah | 11 years ago |buzzdecafe.github.io | reply

111 comments

order
[+] ajanuary|11 years ago|reply
> This means that typeof can now throw

    >>> def f():
    ...     type(x)
    ...     x = 10
    ...
    >>> f()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in f
    UnboundLocalError: local variable 'x' referenced before assignment

    irb(main):010:0> def f()
    irb(main):011:1>     x.class
    irb(main):012:1>     x = 10
    irb(main):013:1> end
    => nil
    irb(main):014:0> f()
    NameError: undefined local variable or method `x' for main:Object
    	from (irb):11:in `f'
    	from (irb):14:in `evaluate'
    	from org/jruby/RubyKernel.java:1101:in `eval'
    	from org/jruby/RubyKernel.java:1501:in `loop'
    	from org/jruby/RubyKernel.java:1264:in `catch'
    	from org/jruby/RubyKernel.java:1264:in `catch'
    	from C:/jruby-1.7.12/bin/jirb_swing:53:in `(root)'

    public class Test {
    	public void f() {
    		boolean isInt = x instanceof Integer;
    		Integer x = 10;
    	}
    }
    >javac Test.java
    Test.java:3: error: cannot find symbol
                    boolean isInt = x instanceof Integer;
                                    ^
      symbol:   variable x
      location: class Test
    1 error
Oh no, it's now in line with just about every other lexically scoped language.
[+] hasenj|11 years ago|reply
`typeof a` right now returns the string value "undefined" (assuming `a` was not defined anywhere)

If it can either return "undefined" or throw an exception, can you see why that would be a problem?

[+] toolz|11 years ago|reply
Except, now you have one that you expect and the other you don't. This doesn't make the language anything but more inconsistent. I prefer consistency inside a language far more than familiarity between languages.
[+] mmahemoff|11 years ago|reply
Whoop-dee-freakin’-doo???

Sure there's a zillion frameworks and patterns for shoehorning OO into JavaScript. But the point is, ES6, is standardising it. That means libraries going forward will assume this is the way it's done and build on top of it. It gives them more expressive power and better inter-op.

Also, default params are long overdue but I'm not sure that makes them "so what". I'd rather avoid mangling the arguments array in some awkward if statements.

Bottom line, there's a lot of things about JS that aren't great, but it's what all the browsers actually run so we're kind of stuck with it and any improvements are welcome.

(Even if you use something like ClojureScript or CoffeeScript, JS is still the target language and the runtime. Improvements and standardisation matter.)

[+] JackMorgan|11 years ago|reply
I think he means OO adds unnecessary complexity, hence the "bad bet".
[+] chriswarbo|11 years ago|reply
How exactly can OO be "shoehorned" into a language which is already OO?
[+] ahoge|11 years ago|reply
>Classes. Whoop-dee-freakin’-doo.

There are dozens of ways to do classes/inheritance. Standardizing this means better tooling, documentation, and interoperability.

>Default parameters. By itself, this is another “so what” feature.

It's extremely useful in conjunction with named parameters. Named parameters are so much better than "option" objects.

If it's right in the function's signature, you can see right away how this thing is supposed to be used. Since it's declarative, it can be also picked up by your editor, too.

>let considered harmful

No, it's not. It makes variable declaration work like everywhere else. Function scope is the super weird anomaly.

[+] cronin101|11 years ago|reply
> let considered harmful

Did people actually use the side-effect var-hoisting intentionally within their code?

Pretty much any JS style-guide worth its salt suggests manually moving var declarations to the top of scope since it's nice to know ahead-of-time which indicators of state you should be keeping an eye on.

The idea of inspecting a variable that is later-on defined with let seems baffling to me. I can't think of any reason why you would want to do this.

[+] kosinus|11 years ago|reply
I tend to declare vars with their context. Especially in functions that are (unfortunately) longer than usual, having all vars at the top makes for a mess.

But I don't think the `let` syntax is going to be a problem for people who write plain JavaScript. It's more likely to it might become a problem for languages that compile to JavaScript. (For example, soak operators in CoffeeScript.)

[+] basicallydan|11 years ago|reply
> let considered harmful: The problem with let is that it is not “hoisted” to the top of its block, as var is with its containing function.

Interesting point, but I disagree. I think that the lack of hoisting is one of the benefits of `let`. It works in a different way, which is more in line with other languages. Sometimes, you don't want a bunch of variables at the top of your function. Many functions do not need to be executed in the way that hoisting makes easier.

By the way, quoting Betteridge’s law of headlines at the beginning of your article whose headline is a question does not mean you get a free pass of using such a headline ;)

[+] gamesbrainiac|11 years ago|reply
This is one of the few posts about javascript that I've encountered that sees hoisting as a good thing. I like `let`.
[+] quarterto|11 years ago|reply
Have you read the linked article about typeof? Normally, it's safe to do typeof possiblyUndeclaredVariable, but if later in the function you do let possiblyUndeclaredVariable it starts the scope defined as "uninitialized", which causes typeof to throw.
[+] ajanuary|11 years ago|reply
That part of the article isn't particularly clear. The intended behavior of let is great. The unintended behavior - that it can cause typeof to fail - is bad.
[+] bananaoomarang|11 years ago|reply
I guess the argument here is that let adds inconsistency? ie: var statements are hoisted and let statements aren't. It's a double edged sword: On the wone hand it can be used to improve readability, but it also adds complexity/more to bear in mind.
[+] gildas|11 years ago|reply
Hoisting is great thing, it is really helpful to improve readability when doing asynchronous function calls.

    function a(){
      setTimeout(b, 1000);
    }

    function b() {
      setTimeout(c, 1000);
    }

    function c() {
    }
[+] phpnode|11 years ago|reply
ES6 is fantastic and usable today using the excellent 6to5 [0]. I disagree with all of the author's points, I think these are great features.

[0] https://github.com/6to5/6to5

[+] collyw|11 years ago|reply
Whats his problem with classes?

I find them a whole lot easier to reason about than prototype based inheritance. (But then I have more experience with class based languages).

[+] tel|11 years ago|reply
Classes are just functions for constructing certain kinds of objects using open recursion. There's nothing wrong with them per se, but their elevated status is confusing. It also might lead to trying to solve all complexity concerns using open recursion. I'm interested in clear analysis about how good or bad that idea is honestly. At this point I just find it (a) not personally necessary and (b) interesting.

As to the author's problem? I imagine it might have some deep seated cause related to the above, but that keeps getting translated to abstract disdain for the concept. Which is tragic.

[+] toolz|11 years ago|reply
I imagine it has something to do with the 'new' functional movement that is gaining mind-share outside of academia.
[+] chriswarbo|11 years ago|reply
Well, even if you prefer classes, you've now got to reason about prototypes and classes, and possible mixtures of both.
[+] vim-guru|11 years ago|reply
Classes adds complexity and reduces composability. With OO you end up with a soup of inheritence and patterns. Functions are way easier to compose and reason about.
[+] robinduckett|11 years ago|reply
I like `let`. It means you have to be implicit and actually be aware of what you're doing.
[+] ajanuary|11 years ago|reply
That part of the article isn't particularly clear. The intended behavior of let is great. The unintended behavior - that it can cause typeof to fail - is bad.
[+] Hypx|11 years ago|reply
JavaScript is definitely getting better. The only question is whether they are changing too much too fast. There'll be a lot of headscratchers when running into unfamiliar ES6 code.
[+] cwmma|11 years ago|reply
So classes in ES6 are something I have very mixed feelings about, on one hand all that is being added is syntactic sugar for what is already being done, I'd like to repeat that ES6 classes add NOTHING that isn't already being done and all it really does is pave the cowpath that is being used in places like node

Currently:

    JSONParseStream.prototype = Object.create(Transform.prototype);
    function JSONParseStream(options) {

    Transform.call(this, options);
        ...
    }
   
    JSONParseStream.prototype = Object.create(Transform.prototype);

    Object.defineProperty(JSONParseStream.prototype, 'constructor', {
        value: JSONParseStream,
        enumerable: false,
        writable: true,
        configurable: true
    }

    JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
        ...
    }
With ES6:

    class JSONParseStream extends Transform {
        constructor(options) {
            super(options);
            ...
        },
        _transform(chunk, encoding, cb) {
            ...
        }
    }
That being said, the fact that previously you could not simply use the word class meant that despite efforts of people unused to the language (let me tell you how many half assed class libraries i've seen in code written by people who mainly code in python or java but have some web code as well), unnecessary inheritance tends to be avoided. The lack of a class keyword tends to get javascript writers to avoid inheritance for things best served by mix-ins or object literals, or whatever. I predict that adding the class keyword, while saving me some time will also cause an uptick to unnecessarily convoluted inheritance patterns as new users find they can implement all of their design patterns verbatim without thinking if they really need the ajax method, the json parser, and the url builder to all be in objects that inherit from each other.
[+] arcatek|11 years ago|reply
I'm sorry, but I really see no point in this article.

Do you realize that if the optional arguments were not included in Function#length, you'd just be saying "They are not reflected in the function’s length property. C'mon, man" instead ?

Also, I don't understand Whoop-dee-freakin’-doo.

[+] Kiro|11 years ago|reply
I don't understand the benefit of fat arrow. I actually think it decreases the readability. What does lexical "this" binding mean?
[+] brazzy|11 years ago|reply
Fat arrow notation massively increases readibility by reducing the boilerplate verbosity of function definitions. Lexical "this" binding means that the "this" of the enclosing scope is reused; Arrow-defined functions do not get their own "this" when they are called.
[+] Skinney|11 years ago|reply
It means it inherits the 'this' of the enclosing function.

Without fat arrow: function outer() { function inner() { this === inner.this; } }

With fat arrow: function outer() { var inner = => this === outer.this; }

[+] tracker1|11 years ago|reply
A lot of times you stuff the context (this) into a variable (like that)... so that you can use it in callback handlers farther down.

Fat arrow syntax is much more terse than a function declaration and also handles the case of passing the parent's execution scope.

[+] Mithaldu|11 years ago|reply
Why didn't they call "spread" by the same name it's called virtually everywhere else, "flatten"?
[+] collyw|11 years ago|reply
I hate this. Why can languages try and standardize on things to at least some extent.

else if (JavaScript) elsif (Perl) elif (Python)

There is no good reason that these are different.

[+] JacobEdelman|11 years ago|reply
Eh, a lot of the additions are improvements, a few are not, a very small few introduce some annoying features. It's an improvement, maybe not perfect, but still a big improvement. Disclaimer: I like JavaScript.
[+] forthefuture|11 years ago|reply
I'm more interested by how many people still seem to be using typeof instead of toString. What are you doing for array checking since typeof array === "object", !!x[0]?
[+] noiv|11 years ago|reply
There is also Array.isArray()