>>> 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.
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.
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.)
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.
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.
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.)
> 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 ;)
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.
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.
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.
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.
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.
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.
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.
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
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.
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 ?
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.
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.
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]?
[+] [-] ajanuary|11 years ago|reply
[+] [-] hasenj|11 years ago|reply
If it can either return "undefined" or throw an exception, can you see why that would be a problem?
[+] [-] toolz|11 years ago|reply
[+] [-] mmahemoff|11 years ago|reply
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
[+] [-] chriswarbo|11 years ago|reply
[+] [-] ahoge|11 years ago|reply
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
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
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
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
[+] [-] quarterto|11 years ago|reply
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] ajanuary|11 years ago|reply
[+] [-] bananaoomarang|11 years ago|reply
[+] [-] gildas|11 years ago|reply
[+] [-] phpnode|11 years ago|reply
[0] https://github.com/6to5/6to5
[+] [-] collyw|11 years ago|reply
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
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
[+] [-] chriswarbo|11 years ago|reply
[+] [-] vim-guru|11 years ago|reply
[+] [-] robinduckett|11 years ago|reply
[+] [-] ajanuary|11 years ago|reply
[+] [-] Hypx|11 years ago|reply
[+] [-] cwmma|11 years ago|reply
Currently:
With ES6: 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
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.
[+] [-] quarterto|11 years ago|reply
[+] [-] Kiro|11 years ago|reply
[+] [-] brazzy|11 years ago|reply
[+] [-] Skinney|11 years ago|reply
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
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
[+] [-] collyw|11 years ago|reply
else if (JavaScript) elsif (Perl) elif (Python)
There is no good reason that these are different.
[+] [-] JacobEdelman|11 years ago|reply
[+] [-] filipncs|11 years ago|reply
When are proper tail calls expected to show up? Looks pretty bleak.
http://kangax.github.io/compat-table/es6/
[+] [-] forthefuture|11 years ago|reply
[+] [-] noiv|11 years ago|reply
[+] [-] jerryluc|11 years ago|reply
[1] http://en.wikipedia.org/wiki/Betteridge%27s_law_of_headlines
[+] [-] collypops|11 years ago|reply
[+] [-] unknown|11 years ago|reply
[deleted]