News for hackers. Stuff that matters.
Re:Classes Are Making Me Sad by shp0ngle on Wednesday March 08, 2017 @04:21PM (#13823913)
Every time I think I understand Javascript, I read something about its prototypes and constructors and how 'new' and 'this' works and I am lost again.

The thing I like about classes is I vaguely understand what is going on and why, coming from Java and similar. So I am using them, together with Flow typechecking.

I am not saying the javascript prototype logic is bad, just that I never understood it, even when I work in Javascript for years.

Sometimes I understand, for a brief moment, "how", but never "why".

Re:Classes Are Making Me Sad by Lazare on Wednesday March 08, 2017 @05:18PM (#13824414)
> Every time I think I understand Javascript, I read something about its prototypes and constructors and how 'new' and 'this' works and I am lost again.

Prototypes, constructors, and context are not that complicated; I encourage you to keep reading and trying things. You may be surprised how quickly you end up "getting" it.

> The thing I like about classes is I vaguely understand what is going on and why, coming from Java and similar.

No. The class keyword in JS is syntactic sugar around the same prototype stuff that already existed. It does not work like it does in Java, and you will not understand what it's doing unless you understand how the class keyword translates directly into manipulating the prototype chain.

Which, as above, is easy! But if there's one actual problem with the class keyword it's that it makes people who know Java think they understand JS inheritance.

The class keyword DOES NOT CHANGE YOUR CODE. If you didn't understand what was going on before you used the class keyword, you don't understand it after adding it in. (Conversely, if you actually do understand how the class keyword works, then rejoice, you now understand how prototypes work...)

Re:Classes Are Making Me Sad by coldtea on Wednesday March 08, 2017 @07:51PM (#13825651)
>Which, as above, is easy! But if there's one actual problem with the class keyword it's that it makes people who know Java think they understand JS inheritance.

Which is totally fine, as for all intends and purposes the behavior is the same. You create new instances, and you call methods on them.

The "movable" context (this) will be a little surprising, but for everything else one can write JS for decades with ES6 classes and "OOP", without having to know how the prototypes, objects and functions they de-sugar to work.

Re:Classes Are Making Me Sad by LyndsySimon on Friday March 10, 2017 @10:59AM (#13839544)
> Which is totally fine, as for all intends and purposes the behavior is the same.

Nope :) They're apparently the same, which is not the same as "the same".

> The "movable" context (this) will be a little surprising, but for everything else one can write JS for decades with ES6 classes and "OOP", without having to know how the prototypes, objects and functions they de-sugar to work.

That's just the thing though - there isn't a "movable context", there is only binding. Binding usually happens implicitly, and most of the time things are implicitly bound to what you expect them to be if you're not aware it's happening.

... then comes the moment that you're in an instance's method, and `this` is pointing to an event instead of the object. Oh, boy.

In my experience that moment comes much more often than once every few decades.

Re:Classes Are Making Me Sad by Ghostium on Wednesday March 08, 2017 @04:34PM (#13824035)
Re:Classes Are Making Me Sad by shp0ngle on Wednesday March 08, 2017 @06:50PM (#13825154)
Yeah, I always understand "how" from books like this, but not "why". Why is javascript like that?

More to the point, what is the reason for prototype-based inheritance, what is its benefit, what more can you do with it than with C++/java, where does it make life easier.

Re:Classes Are Making Me Sad by Joeri on Wednesday March 08, 2017 @05:22PM (#13824463)
My understanding about the how:

- 'this' is based on how you call something, not what it is attached to. It's possible to have a.fn and b.fn be the same function with 'this' referring to each object in turn when you call a.fn() and b.fn().

- Function.bind muddies the waters a little bit, but basically that creates a wrapper that forces 'this' to a particular object.

- a 'class' in js is a function with a prototype property pointing to a parent object / parent class instance (not a class)

- new fn() creates an object, assigns the prototype, and runs fn.call(obj)

- obj.prop walks the chain of prototypes attached to obj until it finds 'prop' on one of the instances

As to the why, the idea is that the core object is the function, not the class, and prototypes are a way of conveniently determining the context a function is executed in. There is no such thing as a class in js, only a class-like syntax to wrangle functions and objects.

Re:Classes Are Making Me Sad by shp0ngle on Wednesday March 08, 2017 @06:46PM (#13825122)
Is there a a reason to learn bind, where I can use arrow function, which is cleaner and more readable? (And probably does bind under the hood)

Also, what is the reason for the prototype style inheritance? What is the benefit? Why use it over "classic", java-style OOP?

Re:Classes Are Making Me Sad by LyndsySimon on Friday March 10, 2017 @12:25PM (#13840221)
> Is there a a reason to learn bind, where I can use arrow function, which is cleaner and more readable? (And probably does bind under the hood)

Off the top of my head, arrow functions come in handy when you're defining an "instance method" that you want to use as an event handler; you want `this` to refer to the instance, not the event. That's 95% of the time you'd use an explicit call to `bind` anyhow.

Another case to use `bind` would be a generic function that isn't specific to the type of object you're acting upon. I wrote up a short example on jsfiddle: https://jsfiddle.net/LyndsySimon/5zqtjd82/

You can also use binding to create decorators that work on instance methods: https://jsfiddle.net/LyndsySimon/n57or0u5/

Re:Classes Are Making Me Sad by Joeri on Thursday March 09, 2017 @01:45PM (#13831807)
In prototype inheritance, objects inherit from objects. This creates flexibility, since you can dynamically create a base object to inherit from. You can also easily augment base objects after they're inherited from. Class-based inheritance is less powerful in most languages due to the increased runtime rigidity of the class hierarchy. That's the theory. In practice everyone treats prototypes as classes.
Re:Classes Are Making Me Sad by mkozlows on Wednesday March 08, 2017 @05:26PM (#13824502)
Which is the problem with "class" in a nutshell.

If you don't understand prototypal inheritance in ES5, you don't use it, and you stick with simpler concepts that work in a clean and elegant way that doesn't depend on OO-like trappings cluttering up your code unnecessarily.

But with that "class" keyword sitting there, it looks vaguely familiar enough, and you just start programming as if it were Java, and your code turns into this complex morass without you even realizing it until the pain starts.

Re:Classes Are Making Me Sad by camus2 on Wednesday March 08, 2017 @05:34PM (#13824578)
> Which is the problem with "class" in a nutshell.

Which is not new with Javascript in general. every single feature in javascript suffers from being strangely familiar while having a behavior specific to Javascript. Comparison operators, var declaration hoisting,function declaration hoisting, "this", "typeof" operators,type equality and coercion rules, and co, all require to actually learn how the language works. This isn't a very good argument against the class keyword. Yes, developers who use a language need to learn it before hand. It applies to all languages.

Re:Classes Are Making Me Sad by iamjs on Wednesday March 08, 2017 @04:39PM (#13824089)
> The thing I like about classes is I vaguely understand what is going on [...] I am not saying the javascript prototype logic is bad, just that I never understood it, even when I work in Javascript for years.

But by using classes, you're still using prototypes, it just isn't as immediately apparent.

Re:Classes Are Making Me Sad by munificent on Wednesday March 08, 2017 @04:52PM (#13824201)
Sure, and by using classes in C++, you're still using tables of functions pointer like you can in C. The "not as immediately apparent" part is where the usability improvement comes from. It means you don't need to think about the machinery as much. You can work at a higher level of abstraction.

(Of course, the details of how the feature is designed determine how leaky the abstraction is and how often you actually get the luxury of not thinking about the machinery.)

Re:Classes Are Making Me Sad by dsp1234 on Wednesday March 08, 2017 @05:57PM (#13824756)
I think understanding "this" in javascript is actually much easier if you have had exposure to C++ function tables.

With that knowledge in hand, it immediately becomes obvious that:

  bar.baz = function(){console.log(this.X)}
  var foo = bar.baz;
  foo();
Is not going to result in a console log of bar.X. "foo" is a pointer-to-member function, and executing it without a context is going to cause problems. The biggest in javascript as compared to c++ is that javascript will always provide the hidden "this" (even if it's the global context), whereas c++ will always bail out if you don't provide it with a proper context.

But really, understanding that behind the scenes, member function calls change:

  A.B(C)

  into

  B(A, C)
clears up a lot of "this" mistakes, and also enlightens the proper usage of function.bind.
Re:Classes Are Making Me Sad by shp0ngle on Wednesday March 08, 2017 @06:45PM (#13825115)
Once I started using arrow notations, I stopped worrying about `this`.

Whenever I need to export class function, I do

    var foo = () => bar.baz()
, no more worrying, no need to understand what the hell bind does exactly.

Also with the ... notation, I stopped worrying about .call and .apply. So I can write

    var someArray = [a,b,c]
    var foo = () => bar.baz(...someArray)
and so on.
Re:Classes Are Making Me Sad by jaredsohn on Wednesday March 08, 2017 @04:36PM (#13824063)
I would encourage you to read https://github.com/getify/You-Dont-Know-JS (ideally all of it, but start by doing searches for 'class', 'prototype', etc.)

Edit: Funny to see someone else post a link to the same book at the same time :)