Live data from Hacker News

ES6 Overview in Bullet Points

github.com

21–30 of 50 posts

Re: ES6 Overview in Bullet Points

#21
post #9
post #3

Looking good and informative, but to be honest I am really interested in use cases. I think I understand how to use generators but I have no idea where I could use them in real-world scenarios. Same goes for WeakMaps, Proxies... Anyone care to give some examples?

Check out http://jlongster.com/A-Study-on-Solving-Callbacks-with-JavaS... and the follow up post. It's easy enough to start using generators alongside your existing async solution (callbacks or promises). Proxies can be used for data-binding, similar to Object.observe. I've also yet to find a case where I need WeakMaps instead of an Object or Map. All the benefits seem to be a bit too theoretical, but I likely haven'…

I've used a WeakMap for a kind of memoization.

Assume an immutable object may undergo an expensive transform that returns an object, which is then stored in a WeakMap keyed to the immutable. When there are no new references to that object, the garbage collector will clean it up, but otherwise the expensive transform may be avoided with a lookup on the WeakMap.

It provides a pretty nice way to decouple your caching from the rest of the codebase.

Re: ES6 Overview in Bullet Points

#22
post #7
post #4

Great writeup. I welcome most of the additions, but I somehow cannot get behind things like: var {foo} = pony is equivalent to var foo = pony.foo var {foo: baz} = pony is equivalent to var baz = pony.foo I am not sure why, but most languages get into a state where they seem to encourage non-readable code. What was wrong with 'var baz = pony.foo' to start with?

the core use case is var { foo } = pony I agree this is kind of silly in isolation, but more often than not, its used like this: var { foo, bar, baz } = pony which is honestly not that hard to read, and is much better than var foo = pony.foo; var bar = pony.bar; var baz = pony.baz; which is very useful when you're referencing properties of pony a lot. Since you're going to see destructuring used like var { foo, bar,…

It's not hard to read if you already know what it does. As it stands, it's a barrier to learning and a detriment to consistency in style.

Re: ES6 Overview in Bullet Points

#23

Earlier quoted context omitted.

I wish they'd let you return stuff this way, like: return {a, b, c} = foo;

What would be the point of that? Just return `foo` and destructor in the callee.

That's definitely another option (and what I use now!), but I do what I posted in Elixir a lot so I guess I'm used to it.

Re: ES6 Overview in Bullet Points

#25
post #3

Looking good and informative, but to be honest I am really interested in use cases. I think I understand how to use generators but I have no idea where I could use them in real-world scenarios. Same goes for WeakMaps, Proxies... Anyone care to give some examples?

checkout Koa to see a great use case of generators. By yielding to asychronous code (instead of callbacks) you can write JS that looks like it's synchronous.

What is the advantage of using generators versus promises?

Re: ES6 Overview in Bullet Points

#26
post #4

Great writeup. I welcome most of the additions, but I somehow cannot get behind things like: var {foo} = pony is equivalent to var foo = pony.foo var {foo: baz} = pony is equivalent to var baz = pony.foo I am not sure why, but most languages get into a state where they seem to encourage non-readable code. What was wrong with 'var baz = pony.foo' to start with?

It's pretty handy when unpacking a JSON blob so you can manipulate individual fields:

  let { b64_img, height, width, filename } = JSON.parse(text)

Re: ES6 Overview in Bullet Points

#27

Earlier quoted context omitted.

checkout Koa to see a great use case of generators. By yielding to asychronous code (instead of callbacks) you can write JS that looks like it's synchronous.

What is the advantage of using generators versus promises?

In this case, Koa uses generators and promises together to emulate the behavior of async/await style concurrency. You can see how Babel 5.x transforms ES7 async/await into generators and promises at https://github.com/babel/babel/blob/v5.8.34/packages/babel/s...

Re: ES6 Overview in Bullet Points

#28
post #22
post #7

Earlier quoted context omitted.

the core use case is var { foo } = pony I agree this is kind of silly in isolation, but more often than not, its used like this: var { foo, bar, baz } = pony which is honestly not that hard to read, and is much better than var foo = pony.foo; var bar = pony.bar; var baz = pony.baz; which is very useful when you're referencing properties of pony a lot. Since you're going to see destructuring used like var { foo, bar,…

It's not hard to read if you already know what it does. As it stands, it's a barrier to learning and a detriment to consistency in style.

That's a general argument against any added feature. The question is, is it useful enough? This particular feature seems valuable and cheap: I write code all the time that would be cleaner with it, and the meaning is natural enough that I independently invented essentially the same syntax years ago as a pair of Lisp macros (dealing in a-lists instead of hashtables).

Re: ES6 Overview in Bullet Points

#29
For those looking for something more in-depth:

ES6 in Depth series @ Mozilla Hacks: https://hacks.mozilla.org/category/es6-in-depth/page/2/?utm_...

The first article in the above series (where you should probably start): https://hacks.mozilla.org/2015/04/es6-in-depth-an-introducti...

Another brief guide to ES6 features, with more code blocks and less bullet points:

https://github.com/lukehoban/es6features

Re: ES6 Overview in Bullet Points

#30
post #14

> Temporal Dead Zone - Attempts to access or assign to foo within the TDZ (before the let foo statement is reached) result in an error Can anybody explain why "let" variables are hoisted to the start of block given this Temporal Dead Zone exists? Is it an artifact of modern JS runtimes? And given the TDZ what practical benefit does knowing that the variable is technically hoisted provide?

I've never liked the phrase 'variable hoisting'. It implies the compiler actively moves the variable declaration.

What's actually happening is lexical scoping - a variable declaration is associated with a lexical scope. For var declarations, the lexical scope is the function, for let declarations, it's the block. When a variable is referenced, it first looks for the variable associated with the lexical scope of the variable reference, then walks up the chain of lexical scopes until it either finds a variable or hits the top scope and the variable doesn't exist.

Lexical scoping is easy to reason about and fairly easy to calculate. The majority of languages used today use lexical scope (the only exception in popular languages I can think of is perl which lets you use either lexical or dynamic scope, though I'm sure there are others).

A consequence of this design is that you can't have multiple variables with the same name in the same lexical scope. Most languages will raise an error if you redeclare a variable - javascript is unusual in that it doesn't.

Javascript is also unusual in that you can reference variables before they're both declared and definitely assigned. It's these design choices, interacting with lexical scope, that gives javascript such weird and notable behaviour that people have decided it needs a name - 'hoisting'.

So why are let variables 'hoisted' to the start of the block? Because that's how every other language does it. Because it's cheap and dead simple to reason about.

If it didn't, that would mean you could have multiple variables with the same name in the same block. That would be more difficult to keep track of, both for the compiler/runtime and for the programmer. It would also be largely pointless, because once execution gets to the code past the second variable declaration, you can't reference the variable created by the first declaration (unless you capture it with a closure).

    function example() {
        let a = false;
        console.log(a);
        let a = 10; // Past this point, I can't get to the first a anymore
        console.log(a);
    }
The TDZ addresses the design decision of being able to reference a variable before it's declared.

    function example() {
        console.log(a); // Without a TDZ, this will print undefined. With TDZ, this will be an error.
        let a = 10;
    }
If you google around for examples of 'hoisting' gone bad and run through what would have happened if vars had TDZ, you'll see that all of them would be avoided.

Why is it useful to know both about block scoping and TDZ?

Block scoping lets you know that:

    function example(b) {
        let a =10;
        if (b) {
            let a = 20;
            console.log(a); // This will print 20, because it refers to the variable in the if block
        }
        console.log(a); // While this will print 10, because it refers to the variable in the function block
    }
While TDZ lets you know that:

    function example() {
        console.log(a); // This will raise an error
        let a = 10;
    }
Post reply on HN