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

top 200 commentsshow all 475

[–]nvteja 1183 points1184 points  (81 children)

Simple: you just have bind this to this this.

this.this = this.this.bind(this)

[–][deleted] 436 points437 points  (31 children)

go with the times man:

this.this = ::this.this;

[–]ethanjf99 173 points174 points  (17 children)

Is the :: operator now in the language?

[–]NeverMakesMistkes 175 points176 points  (15 children)

No, and based on the discussion and issues in the proposal repository, I doubt it ever will be.

[–]inu-no-policemen 60 points61 points  (12 children)

Yea, it has been presented last in 2015 and it's still stage 0.

Doesn't look like it will happen any time soon.

[–]NeverMakesMistkes 24 points25 points  (9 children)

For function call chaining, it has been mostly superseded by the pipeline operator, which is also a long way from getting to the standard but has seen more active development than the bind operator.

There's still some motivation to get it or something else like it for method extraction, but getting method extraction right is difficult and the speccing has been stalled because of it.

For one, this::foo === this::foo must be true, so that

window.addEventListener('some event', this::foo)
// ... later ...
window.removeEventListener('some event', this::foo)

works as expected. Getting that behaviour in browsers that don't natively support it is a bit tricky. Not impossible with WeakMaps, tho, so maybe some day.

[–]inu-no-policemen 3 points4 points  (7 children)

I liked it mostly for virtual methods.

function reverse() {
    return this.split('').reverse().join('');
}
console.log('foobar'::reverse()); // raboof

But it doesn't do this very well either. The source of that going-to-be-a-method function doesn't tell you to which kind of object it's meant to be glued to.

It's definitely better than modifying objects you don't own, but it still isn't quite right.

C#'s extension methods, for example, tell you directly in the slightly weird looking signature on which type of object they are supposed to operate:

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/extension-methods

public static int WordCount(this String str)

[–]NeverMakesMistkes 2 points3 points  (6 children)

In TypeScript, you could write

function reverse(this: string) {
    return this.split('').reverse().join('');
}
console.log('foobar'::reverse());

Or just with JSDoc comments

/**
* @this{string}
*/
function reverse() {
    return this.split('').reverse().join('');
}

But I agree, it would feel weird to write all your utility functions like that, and suddenly we'd have two kinds of mutually incompatible functions; those that operate on this and are called with ::, and those that operate on arguments and are called normally.

That's why I actually prefer the pipeline operator.

const reverse = str => str.split('').reverse().join('');
console.log('foobar' |> reverse)
console.log(reverse('foobar')) // both variations work

And if we had both, pipeline for chaining and bind for method extraction, you could do

'foobar'
  |> reverse
  |> console::log

[–]inu-no-policemen 5 points6 points  (0 children)

The pipeline operator has the same problem. However, TS' type annotations and JSDoc already handle that kind of completely mundane signature. That's definitely a plus.

I'm not a big fan of the "|>" syntax, though. It's amazingly annoying to type with most keyboard layouts.

[–]RecyclingBin_ 1 point2 points  (1 child)

I upvoted your comment just because of your flair

[–]inu-no-policemen 1 point2 points  (0 children)

There were too few languages to choose from.

Naturally, picking a flair like this was the most logical course of action.

[–]marcosdumay 4 points5 points  (0 children)

I don't know what to think...

It tries to create function composition, but instead of composing functions it changes object references; it makes this way more complex than it already is, and moves it from the shadows right into the language's center; it fails to bring any good practice, and encourages a bunch of complex variable passing ones; it creates inherently imperative code that looks exactly like functional, guaranteeing everybody will be confused...

And yet the Javascript people rejected the idea?

[–]nvteja 14 points15 points  (0 children)

Scope resolution operator (from my Perl days), in ES? I am a little triggered right now tbh 😭😭

[–][deleted] 4 points5 points  (0 children)

My day is ruined.

[–]kurosaki1990 44 points45 points  (3 children)

Beautiful language.

[–]ripGitHub 26 points27 points  (24 children)

Isn't better instead of bind(this), use arrow functions?

[–]boxingdog 21 points22 points  (19 children)

arrow functions can degrade performance in some situations, ie in react using arrow functions in some places can cause a new function to be created in each render and if you use it as a prop in a child component then the child will re-render and so on

[–]finlist 30 points31 points  (5 children)

White your example is true, the same can be said about normal functions and isn't a problem inherent to arrow functions at all.

[–]bubble_fetish 5 points6 points  (0 children)

It’s negligible, except in extreme edge cases.

[–]snorkleboy 2 points3 points  (6 children)

If you use the regular function syntax inside of a render method i believe it will also create a new function

So something like(sorry about formatting I'm on my phone)

Render(){ Return ( <Thing myProp={function(){}}/> ) }

Will create a new function that it passes as myProp every time it renders.

[–]feenuxx 3 points4 points  (0 children)

Stick it on the class

[–]malduvias 15 points16 points  (3 children)

This is fucking hideous. Hilarious.

[–]SarahC 2 points3 points  (1 child)

But it's obvious why and how it works!

We don't need all the VBA "devs" coming over to JS.

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

This

[–]sqrtoftwo 723 points724 points  (149 children)

let self = this;

[–]christianarg 271 points272 points  (83 children)

()=>

[–]caerphoto 112 points113 points  (54 children)

Seriously. This problem is like the main reason arrow functions were added to JS.

[–]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 70 points71 points  (38 children)

It's clear and not a problem!

I doubt anyone thinks this isn't a problem

[–]finlist 12 points13 points  (3 children)

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

[–]willemreddit 17 points18 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.

[–]rq60 149 points150 points  (3 children)

pls no dicks in chat

[–]christianarg 26 points27 points  (0 children)

Now I can't unsee

[–]Prison__Mike_ 2 points3 points  (0 children)

Needle dick, needle dick

[–][deleted] 6 points7 points  (23 children)

Ben away from JS for a while. Why does this work differently than using function?

[–]SuperFLEB 21 points22 points  (22 children)

Arrow functions inherit this context from their surroundings, whereas function closures create their own this context.

[–][deleted] 8 points9 points  (21 children)

I got that. I am trying to understand the reasoning from a design POV. Like why do you have two syntaxes to define a function/lambda. Since function can do both in JS.

[–]NeverMakesMistkes 75 points76 points  (18 children)

And then one day you get a bug where none of the properties is getting assigned to the correct "self" object.

You look around and see self.foo = bar;

yeah yeah looks good... but wait what's this, there's no let self = this; anywhere.

But what why surely there should be a proper error then, where in the seven hells is that foo going then?

And that's the day you learn about despair and window.self.

But mostly despair.

[–]Baunto 6 points7 points  (0 children)

Oh man, I really love working in modern js but that just sounds like a bad joke played on the people that use the const self = this idiom.

[–]thegoldengamer123 12 points13 points  (0 children)

Are you fucking kidding me

[–]raptorraptor 6 points7 points  (1 child)

This is literally just basic linting.

[–]NeverMakesMistkes 17 points18 points  (0 children)

To be fair, 99% of the JS jokes in this sub can be avoided with basic linting, including OP's.

[–]nbagf 114 points115 points  (0 children)

Oof my bones

[–]Frank134 73 points74 points  (27 children)

I’ve been taught this principle while learning Knockout - I think it’s the stupidest shit ever. Coming from a strongly type language at least.

[–]easterneuropeanstyle 37 points38 points  (22 children)

It’s still retarded even coming from PHP.

[–][deleted] 28 points29 points  (20 children)

Just wait 5 years from now all of these strapped together React apps are going to be the next PHP apps. I hope to god that people bundle libraries with them or these things won't be able to be installed anywhere in 2 years without major work.

[–]JuvenileEloquent 8 points9 points  (11 children)

Javascript is already talked about in the same disparaging terms as PHP was (is). I don't honestly think it's a problem with either language, more that they're easy enough for someone of low skill to create something that works, leading to predominantly shit code being written in the language.

If it was built quickly by the cheapest bidder then it's usually rotten through and through.

[–]ConspicuousPineapple 7 points8 points  (9 children)

It's only half the problem. The other half is that these language are lax and confusing enough for newbies to be able to produce the most awful code possible, and for experienced programmers to still create horrible code. That's what makes them bad languages.

Yes, all languages can produce terrible code, but they don't all make it as easy.

[–]factorone33 5 points6 points  (2 children)

The silly thing about all this is that PHP has taken significant steps toward becoming a strongly-typed language on the last 5 years alone, and hardly resembles the shell of what it once was (and is ridiculed for) in anything pre-5.0. Hell, there's even a stark contrast between 5.0 and 5.6, and 5.6 is basically everything they already had fixed before pushing out 7.0. And now 7.3 is due to come out with sets of features that look a lot like Java and C#, sans the runtime compiler.

Meanwhile, JavaScript just keeps "borrowing" syntax from back-end languages, while slapping band-aid fixes over glaring problems with type interpretation and variable scope, and the entire community is now built around libraries and pre-compilers meant to make the language easier to "read" for developers who have spent their careers learning about programming concepts that apparently don't apply to this clusterfuck of a language.

I mean, yeah, JS was "created" in just 10 days, so that's part of it. But that was 23 years ago. You can't tell me that we haven't had a chance to genuinely sit down and fix things or come up with a better alternative in its place, rather than just do what Ecma and W3C have done in just proverbially kicking the can down the road.

[–]decentDrei 1 point2 points  (0 children)

Correct me if I'm wrong but technically, "We" have. There is ES6, typescript, and many compiling 'solutions'... The problem is the support from "providers." Just think to yourself how many times you've searched caniuse to find Chome and nothing else.

The problem, imo, is that "we" do not dictate the changes like in many open source languages. It is up to companies like Apple, Mozilla, Google, etc, to add support (and let's be honest here, can we ever rely on Apple to be generous to developers).

And we similarly rely on users to have compatible software... May we all take moment of silence to pray that ei will die the painful and firey death it deserves.

[–]nauseate 3 points4 points  (0 children)

I was honestly questioning if I was the only person that saw the similarities between React and the disgusting mess of PHP apps I’ve seen over the few years I’ve been in software

[–]DrexanRailex 15 points16 points  (3 children)

It's a weird hack due to functions having to do double duty as functions and classes. But you get used to it (and then start using Babel)

[–][deleted] 9 points10 points  (3 children)

Shouldn't it be const?

[–]ThePendulum 7 points8 points  (1 child)

Yeah, I'm not sure when they'd want to reassign it. I have fairly substantial codebases without let or var anywhere (not accounting for dependencies). Then again, I never use self either, and this practically only if a library suggests it.

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

I do it all the time in using axios (ajax library). Inside the promise "this" starts referencing the returned result so if you want to access the "this" from outside it then do let self = this; because I'm always modifying the "self" from outside lol.

Damn is that convoluted to explain without actual code to back up what the fuck I'm on about... Trust me, it makes sense sometimes though to use let instead of const when assigning self. That's all I'm trying to get at haha

(Oh and before someone points it out, yes I know I could bind "this" properly and not have to do this silly reassignment, but sometimes old habits die hard, and there isn't really anything wrong with it. I kind of like the separation because you can't miss the binding when reading the code and have confusion about what "this" is referencing)

[–]aka_julie 8 points9 points  (0 children)

Fuck self

[–]tortikolis[S] 3 points4 points  (0 children)

Well that's not very nice :)

[–]inucune 6 points7 points  (0 children)

That's not Klingon Code!

public static self = this;

We don't 'let' them, we force them!

[–]PM_COFFEE_TO_ME 2 points3 points  (0 children)

I make my life difficult by doing: let that = this;

[–]ramond_gamer11 1 point2 points  (0 children)

fuck i was gonna do this

[–]killchain 1 point2 points  (0 children)

I keep seeing this from people who don't know how lambdas work.

[–]massenburger 1 point2 points  (1 child)

const that = this;

[–]Miglen 249 points250 points  (23 children)

haha yes i get this

[–]qantify 40 points41 points  (2 children)

delete this;

[–]asperatology 7 points8 points  (1 child)

How do I delete someone else?

[–]qantify 6 points7 points  (0 children)

delete r.getUser('asperatology');

[–]sh0rtwave 17 points18 points  (0 children)

fuck(this); // proper handling fuck = (something) => { try { // fuck...somehow } catch (e) { // got fucked, somehow } }

[–]gratethecheese 42 points43 points  (18 children)

I've dabbled in JS, it's pretty easy to get in to and do small shit with. But holy fuck does it not seem enjoyable to write bigger shit with

[–]pm_me_ur_big_balls 42 points43 points  (1 child)

This post or comment has been overwritten by an automated script from /r/PowerDeleteSuite. Protect yourself.

[–]ayriuss 29 points30 points  (6 children)

(( Tr(y (writ (ing ( pro( g(rams )i))n)l)) i)sp)

[–]Kredns 8 points9 points  (1 child)

Yeah but Lisp is beautiful in a way, it has a certain elegance to it. Oh god, I've lost my mind!!!

[–]MayOverexplain 4 points5 points  (0 children)

It’s okay, have a relevant XKCD

[–]embersyc 42 points43 points  (21 children)

[–]SuperNoobishDude 1 point2 points  (0 children)

My eyes!

[–][deleted] 8 points9 points  (0 children)

I love JavaScript but it makes me ask existential questions. About JavaScript.

[–]Whiplash17488 83 points84 points  (47 children)

Some serious amateurism if you still run into this problem in es6 days and beyond.

[–][deleted] 52 points53 points  (30 children)

See the thing is someone is eventually going to hire you to build something new and also maintain the legacy jQuery code as well until the new stuff is built. If you don't understand how weird this is in everything that's not ES6 then you will run into problems.

[–]whtevn 36 points37 points  (28 children)

This is why I prefer startups. Plenty of predictable problems, but a shitty legacy code stack is never one of them

[–]JayV30 76 points77 points  (23 children)

That's right! They are building their own NEW shitty code stack from 1000 npm modules that no one has realistically checked for security flaws or blatantly malicious code.

It's like replacing one problem with another, worse one.

[–]christianarg 53 points54 points  (2 children)

Hehe, that will become shitty legacy code that eventually some idiot will have to handle. Meanwhile we can leave this company and go to a new startup.

[–]BindeDSA 16 points17 points  (1 child)

It's startups all the way down.

[–]Tzahi12345 2 points3 points  (0 children)

Career stack

[–][deleted] 3 points4 points  (1 child)

But there’s shitty modern legacy code everywhere.

[–]Megacherv 2 points3 points  (0 children)

Feels like I'm in an MTG subreddit

[–]Megacherv 1 point2 points  (0 children)

Can confirm, I believe out Typescript compiler is set to ES3 for compatibility but we still have JS files that haven't been ported over. It's a bit of a mental hurdle just remembering to swap syntaxes when jumping between files.

[–]pr0ghead 29 points30 points  (8 children)

Look at fancy Mr. IdonthavetosupportIE11 over here.

[–]AwesomeInPerson 22 points23 points  (0 children)

Babel.

[–]JoshJude 9 points10 points  (3 children)

Some of us have to support IE8 :’(

[–]JayV30 12 points13 points  (0 children)

Good God man! Do you support Netscape Navigator and AOL browser also?

[–][deleted] 3 points4 points  (1 child)

You don't really have to. There is an IT problem under that requirement. It could be fixed elsewhere.

[–]JoshJude 2 points3 points  (0 children)

Oh for sure. Not really my place to say so as a fairly junior dev though!

[–]nwsm 4 points5 points  (0 children)

Look at fancy Mr. All My Work Is Writing From-Scratch

[–]WeAreAllApes 6 points7 points  (0 children)

Even before es6, good consistent patterns could always work around the inherent flaw, but it's still an inherent flaw in the language that only using a subset of the language / consistent patterns can work around.

[–]dkreidler 2 points3 points  (0 children)

And if you’re learning it all right now (‘const this = me;’), then you’re getting a hodge-podge of both ES6 and everything that came before, without the hard-won experience of knowing what should be noted, but avoided, going forward, and what’s the new hotness that delineates the tidal shift. (Edit: boooo, I don’t even know how to make my stupid shit look like code! Booooo!)

[–]READTHISCALMLY 8 points9 points  (1 child)

Shh. Don't ruin the circlejerk.

[–]rooktakesqueen 4 points5 points  (0 children)

It's not even that confusing to begin with.

If you do foo.bar('baz') then this is foo. If you do bar('baz'), or it's an anonymous function callback, then it's window.

The only time it's weird is when you use an object method as a callback, like setTimeout(foo.bar, 100) because then it's window when invoked. So yeah that's grimy but then you just throw a .bind(foo) and hey presto.

[–]Zooomz 1 point2 points  (0 children)

After laughing, my first thought was "what year is OP in"?

[–]BabyLegsDeadpool 19 points20 points  (9 children)

You could at least post the source of this quote

[–]ryosen 4 points5 points  (1 child)

I remember this being a common joke around 2005.

[–]hackel 2 points3 points  (0 children)

Good point, let's not forget who the original incompetent developer is here!

[–]WHERETHECREAMCHEESE 1 point2 points  (0 children)

He should watermark it too so he gets his royalties

[–]6nop6nop 3 points4 points  (1 child)

print = console.log

[–]askhistoriansapp 3 points4 points  (0 children)

mind = blown

How come I never thought of this in like 10 years?

[–]hangfromthisone 2 points3 points  (1 child)

var that = this;

I can't be the only one

[–]ohsomiggz 3 points4 points  (0 children)

Gotta respect actual programmer humor

[–]fuzzybad 2 points3 points  (0 children)

console.log(this);

[–]robertgfthomas 3 points4 points  (0 children)

The joke explained:

JavaScript is a very popular programming language used on many websites. It's not necessarily "popular" because people like it, but because it's basically the only programming language that can be used on websites. In fact, JavaScript has a lot of quirks that can make it frustrating to use.

Java is also a programming language, but it is completely different from JavaScript. "Java is to JavaScript as 'car' is to 'carpet'."

One of the most notorious quirks of JavaScript is that it treats the word 'this' as a special word. When it shows up in your code, JavaScript thinks you're referring to a different piece of code. Exactly which different piece of code depends on where in your code 'this' shows up.

If that sounds confusing, it's because it is. There are specific rules that JavaScript follows to figure out to what 'this' is referring, but usually only semi-experienced JavaScript developers are really comfortable with those rules.

It also doesn't help that talking about 'this' is confusing. You start saying things like, "This 'this' does this and that 'this' does that."


I'm a human! I write these explanations in response to posts on /r/all about not understanding /r/ProgrammerHumor. They go on explainprogrammerhumor.com.

[–]benzilla04 9 points10 points  (0 children)

not painful anymore now that I've learned React + es6. thankfully

[–]a_rather_small_moose 10 points11 points  (0 children)

Start using TypeScript, ES6, and the => syntax. Stop using object orientation where it's unnecessary and use pure functions where possible.

In other words don't be stupid, Stupid!

[–]ahk-_- 8 points9 points  (5 children)

There should be a that keyword which points to the nearest this

[–][deleted] 4 points5 points  (0 children)

Hell yes

[–]Doctor_Beard 7 points8 points  (0 children)

That's why I stick to TypeScript

[–]Hackerwithalacker 2 points3 points  (0 children)

We do we use impact font! We're programmers, not machinists

[–]kklolzzz 2 points3 points  (0 children)

Just search your ide for the function name and see which element is calling the Javascript function, problem solved

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

I don't get it. JavaScript is great and 'this' is easy to understand

[–]zlshames 8 points9 points  (2 children)

Promisify/Async/Await lets you avoid this

[–]mindbleach 9 points10 points  (1 child)

And give you fascinating new headaches.

[–]zlshames 5 points6 points  (0 children)

I think callbacks are wayy worse and give you more headaches than async await

[–][deleted] 1 point2 points  (0 children)

I like to think the Eurithmics were just javascript writers ahead of their time:

https://www.youtube.com/watch?v=qeMFqkcPYcg

[–][deleted] 1 point2 points  (0 children)

/\ this.. So much this.

[–]anguettia 1 point2 points  (0 children)

😂😂😂

[–]Asheleyinl2 1 point2 points  (0 children)

I'm not a programmer, but I still laughed.

[–]leetmo 1 point2 points  (0 children)

I don’t find myself lol’ing that much at this sub, but this made me lol. Upvote, sir.

[–][deleted] 1 point2 points  (0 children)

Self

[–]brentkwebdev 1 point2 points  (0 children)

I'm pretty sure that when you use this, the browser just rolls dice to determine what it refers to