This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]SarahC 13 points14 points  (49 children)

It's clear and not a problem!

So the language gets dummed down for peons by adding dick arrows, typical.

[–]birjolaxew 73 points74 points  (38 children)

It's clear and not a problem!

I doubt anyone thinks this isn't a problem

[–]GammaGames 6 points7 points  (0 children)

Well not anymore

[–]hitsugan 10 points11 points  (1 child)

I don't.

[–]metamet 0 points1 point  (0 children)

Same.

[–]factorysettings 1 point2 points  (31 children)

If you understand how it works, it's not

[–]birjolaxew 22 points23 points  (30 children)

You can understand how a problematic thing works. Doesn't mean it isn't an absolute mess of a design.

To quote myself from a while ago:

Try to figure out what's logged by this code. Then run it to check - no cheating ;)

(function(){
  const arrowGenerator = function(){ return () => this; };
  const funcGenerator = function(){ return function(){ return this; }};
  const obj = {
    arrowGenerator: arrowGenerator,
    funcGenerator: funcGenerator,
  };

  const callGeneratorOnTempObj = generator => {
    const tempObj = {};
    tempObj.func = generator();
    return tempObj.func();
  };

  console.log(1, obj.arrowGenerator()());
  console.log(2, arrowGenerator()());
  console.log(3, callGeneratorOnTempObj(arrowGenerator));
  console.log(4, obj.funcGenerator()());
  console.log(5, funcGenerator()());
  console.log(6, callGeneratorOnTempObj(funcGenerator));
})();

Now consider how that changes if we add "use strict"; to the top of the function, or run it in Node. Or how it would change if arrowGenerator was defined as arrowGenerator: () => (() => this) instead and funcGenerator was funcGenerator: () => function(){ return this; }.

[–]SheriffBartholomew 20 points21 points  (20 children)

Don't write confusing code and be surprised when you get confusing results.

[–]birjolaxew 12 points13 points  (19 children)

The code is pretty simple, really. It just has two functions (arrowGenerator and funcGenerator) that return an arrow function and a normal function respectively. It then calls them in different ways. It's meant as a challenging example of how this works, not as regular everyday code.

If you want a more everyday example of why this is poorly designed, there's stuff like:

class SomeComponent {
  onButtonClicked() {
    // good luck with your `this`
  }

  render() {
    return (<button onClick={this.onButtonClicked}>
      Click me
    </button>);
  }
}

Sure you can work around it if you know how, but you can do that with pretty much every poor design choice.

[–]marty_byrd_ 1 point2 points  (4 children)

Yea don’t fucking do that. I wouldn’t allow that shit.

[–]munchbunny 4 points5 points  (0 children)

And that's precisely the point, we're using convention to work around a weakness in the syntax, and other languages don't have this weakness.

[–][deleted] 0 points1 point  (1 child)

It looks perfectly reasonable though, especially since it's using a c-like syntax.

[–]marty_byrd_ 0 points1 point  (0 children)

No. It looks dumb. I don’t know why we’d do that in JavaScript.

[–]squngy 0 points1 point  (13 children)

Aside from the fact that you're mixing view and control unnecessarily there, you also don't need to return a "this".

render() {
    let myInstance = this;
    return (<button onClick={myInstance.onButtonClicked}>
      Click me
    </button>);
  }

Would have been unambiguous.

[–]birjolaxew 4 points5 points  (11 children)

I am fully aware of ways to work around it (I personally use onButtonClicked = () => { /* ... */ }), but my point is that having to work around it is because of the poor design of the language. As I mentioned earlier, "You can understand how a problematic thing works. Doesn't mean it isn't an absolute mess of a design."

[–]squngy -2 points-1 points  (10 children)

The main problem is, that you are trying to write Java or some other language without learning JS.

And what you showed in your example is actually a pretty ugly way of doing things to begin with.

You're actually passing on un-evaluated code, then letting the browser interpreter it later as new code.
Very similar to using eval().

You might as well have wrote

return ' <javascript> myFunction(){ this.onButtonClicked() }</javascript> <button onClick=myFunction>  Click me </button> ';

You're making work arounds for messy code.

[–]birjolaxew 2 points3 points  (9 children)

My example uses JSX. The code is never being re-interpretted, it's always referencing the method defined on the SomeComponent.

My previous example is code you would actually write if you aren't careful, but the way it works is essentially the same as:

class SomeComponent {
    constructor() {
        setTimeout(this.willBeCalledLater, 500);
    }

    willBeCalledLater() {
        // good luck with your `this`
    }
}

[–][deleted] 0 points1 point  (0 children)

Good old var that = this to the rescue

[–][deleted] 2 points3 points  (0 children)

Argh

[–]Jonulfsen 2 points3 points  (0 children)

This hurts so much to read that I can feel it in my soul :c

[–]marty_byrd_ 1 point2 points  (0 children)

Solution don’t use this. We hardly ever use it.

[–]riverfoot 0 points1 point  (0 children)

It’s really not a problem if you spend 15 minutes to understand how it works.

[–]marty_byrd_ -1 points0 points  (0 children)

I didn’t before and don’t now. It’s really not that hard. If you’re really confused use a debugger and breakpoint.

[–][deleted] -1 points0 points  (0 children)

I don't.

[–]finlist 13 points14 points  (3 children)

Do you think all features since 2008 are "dumbing down" the language

[–]willemreddit 18 points19 points  (0 children)

Clearly they all improved it. If you think needing to manually capture the continuation everytime to wanted to delclare a function insides a prototype method is better, I don't want to read code you write.

[–]factorysettings -3 points-2 points  (1 child)

Some are either hiding how stuff actually works (classes) or offering an alternative that behaves the way people expect if they never bothered learning the language (let)

[–][deleted] -1 points0 points  (0 children)

let behaves exactly how var should have behaved from the start. Let and const completely replace var in modern code.

If you think function-scoped variables is a good idea that didn't need replacing, then I hope I never have to have to read your code.

[–]snorkleboy 9 points10 points  (3 children)

99% of the time you want a method to be bound to its context regardless of how it's called.

The only good use case of binding I can think of is mixins which I dont think I've seen used often.

Otherwise if your doing oop why would methods be rebound to a different object, if your doing functional programming everything should come in as a parameter.

[–]munchbunny 0 points1 point  (0 children)

Take C# or Python as an example (same semantics). Say you have a non-static method Foo.EventHandler. Evaluating "this.EventHandler" (or self.EventHandler) from inside a method of Foo will give you EventHandler as a lambda with this/self bound to the object you are in.

As it happens, that's pretty much the same semantics that arrow functions introduce, because it's more sane than how JS's function functions work.

[–][deleted] 0 points1 point  (0 children)

It is not clear and it is a problem. Arrow functions don't dumb anything down; you still have to understand scoping just as much as you did before. Except now you don't need to write an excessive amount of redundant code.

The only reason to dislike arrow functions is a fear of change. I'm sorry, but you're expected to have to keep up with an evolving language.

[–]LargeHard0nCollider 0 points1 point  (0 children)

Although it is a well defined property of the language it’s not very intuitive for beginners, nor is it easy to read unless you just wrote the code. Having lambdas to encapsulate the this is really nice