JS Classes and This

I'm curious if there is a way to avoid using arrow functions for methods you want to keep bound to the instance. For example,
class Pog{

works = () => console.log(this)

notworks(){
console.log(this)
}
}

const pog = new Pog()
const works = pog.works
const notworks = pog.notworks

works() // Pog {...
notworks() // undefined
class Pog{

works = () => console.log(this)

notworks(){
console.log(this)
}
}

const pog = new Pog()
const works = pog.works
const notworks = pog.notworks

works() // Pog {...
notworks() // undefined
63 Replies
Samathingamajig
the annoying way is
class Pog{
constructor() {
this.works2 = this.works2.bind(this);
}

works = () => console.log(this)

notworks(){
console.log(this)
}

works2() {
console.log(this);
}
}
class Pog{
constructor() {
this.works2 = this.works2.bind(this);
}

works = () => console.log(this)

notworks(){
console.log(this)
}

works2() {
console.log(this);
}
}
benten
bentenOP3y ago
I know I can do const notworks = pog.notworks.bind(pog) but thats way worse than an arrow fn
Samathingamajig
what do you have against using arrow functions?
benten
bentenOP3y ago
I think they're less readable But thanks, works2 is what I was looking for i guess
Jon Higger (He / Him)
I don't think many people would agree with that sentiment if the alternative to arrow functions is manually binding the this keyword IMO
benten
bentenOP3y ago
Yeah it feels icky
Jon Higger (He / Him)
I mean it's probably good to learn some of the outdated JS stuff so that way you get to know the gotchas in case you're in a codebase with it.
benten
bentenOP3y ago
do people just...always use arrow functions in classes then?
Jon Higger (He / Him)
pretty much I think
benten
bentenOP3y ago
fair enough
Jon Higger (He / Him)
I also think (I could be wrong), in typescript it does that for you So I'll see the ES5 syntax in typescript more often
benten
bentenOP3y ago
no i was running into an issue with this in ts
Jon Higger (He / Him)
interesting I know notworks works in that example, maybe it's a version thing?
benten
bentenOP3y ago
Well, that works but the example would actually be calling
const foo = a.notworks
foo() // undefined
const foo = a.notworks
foo() // undefined
Not sure if it's a TS thing tho, the difference is that notworks() assigns the method to the prototype and works = () => assigns the method to the instance I've literally gone years without knowing how this works in js lol
Jon Higger (He / Him)
Yeah I think I was straight wrong about the TS thing my bad
benten
bentenOP3y ago
all good its fucking confusing it's stuff like this that really highlights how shit JS really is and the monumental job ES6 did to make it decent for most cases
Jon Higger (He / Him)
Sometimes I don't think I give enough credit to JS haters. In hindsight it feels like there's a bunch of pitfalls that's just like "Oh that whole thing I just never do and I'm fine, I don't see why everybody hates JS so much"
benten
bentenOP3y ago
Yeah until you do and then you realise they might have been more right than you thought
Jon Higger (He / Him)
I will say I think in TS, if you opt in to functional programming, it can be an extremely nice langauge, and alot of the footguns are extremely avoidable.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Samathingamajig
the
class Pog{
a() {
console.log(this);
}
}

const p = new Pog();
p.a(); // works
const aa = p.a;
a(); // doesn't work
class Pog{
a() {
console.log(this);
}
}

const p = new Pog();
p.a(); // works
const aa = p.a;
a(); // doesn't work
model is like
function Pog {};

Pog.prototype.a = function a() {
console.log(this);
};

const p = new Pog();
p.a(); // works
const aa = p.a;
aa(); // doesn't work
function Pog {};

Pog.prototype.a = function a() {
console.log(this);
};

const p = new Pog();
p.a(); // works
const aa = p.a;
aa(); // doesn't work
(the method belongs to the class, not the instance) the
class Pog{
b = () => {
console.log(this);
}
}

const p = new Pog();
p.b(); // works
const bb = p.b;
bb(); // works
class Pog{
b = () => {
console.log(this);
}
}

const p = new Pog();
p.b(); // works
const bb = p.b;
bb(); // works
model is like
function Pog() {};
const p = new Pog();
p.b = function b() { console.log(this); };

p.b(); // works
const bb = p.b;
bb(); // works
function Pog() {};
const p = new Pog();
p.b = function b() { console.log(this); };

p.b(); // works
const bb = p.b;
bb(); // works
or
function Pog() {
this.b = function b() { console.log(this); }
};

const p = new Pog();
p.b(); // works
const bb = p.b;
bb(); // works
function Pog() {
this.b = function b() { console.log(this); }
};

const p = new Pog();
p.b(); // works
const bb = p.b;
bb(); // works
(the method belongs to the instance) i think
Develliot
Develliot3y ago
Why would you not just have a function that returns an object literal, class syntax is cursed and should never have been put into JS As a rule of thumb if you have to touch .prototype or constructor you've probably fucked up. That whole period when they tried to make JS look more live Java was an evolutionary dead end and caused nothing but confusion.
benten
bentenOP3y ago
Because classes are dope and i like having protected methods
Develliot
Develliot3y ago
You can have a function within a function and just not return it, protected, yay closures.
Samathingamajig
bad take
Develliot
Develliot3y ago
The fact that some things work sometimes and other things don't work other times means it's best avoided, vs functional programming, arrow functions and object literals which work every time, have less cognitive load, side steps any lexical scope issues with 'this' and don't go against the grain of what JS is, it's best to not crow bar JS into being OOP.
benten
bentenOP3y ago
So how can I access this method from inherited classes then? Protected is different than private
Develliot
Develliot3y ago
By not building with inheritance and building via composition
benten
bentenOP3y ago
No thanks, classes work fine for my usecase
Develliot
Develliot3y ago
You want functionality you add it, don't want it don't add it. None of this public/private/protected stuff helps anyone.
benten
bentenOP3y ago
k.
Develliot
Develliot3y ago
Brian Will
YouTube
Object-Oriented Programming is Bad
An explanation of why you should favor procedural programming over Object-Oriented Programming (OOP).
Develliot
Develliot3y ago
6 years old and a fair analysis still relevant today I picked that video because it is nowhere near as harsh as some of the others
benten
bentenOP3y ago
InfoQ
YouTube
Functional Programming is Terrible
Rúnar Bjarnason loves functional programming, but here he plays devil's advocate and addresses some of its shortcomings. (Don't worry, there's a happy ending). ** Scala training from NewCircle: https://newcircle.com/category/scala http://nescala.org/
Develliot
Develliot3y ago
The video I showed is not even covering issues that are specific to JS like lexical scope issues
benten
bentenOP3y ago
Theres videos trashing every programming style, you aren’t helping anybody by telling them their chosen paradigm is shit when they just wanted help with a JavaScript keyword I’m not rewriting my fucking codebase because you don’t like OOP I’m so sick of people trashing OOP, the entire internet runs on it while FP is confined to academia Like the whole point of strict FP is to write functions that can be easially proved
Develliot
Develliot3y ago
The video trashing FP doesn't translate to JS or TS
benten
bentenOP3y ago
I’m well aware of the advantages and disadvantages of OOP and functional styles, there isn’t one that is better than the other for literally every task But FP evangelism is fucking annoying, don’t see OOP languages with that problem But that’s mainly a product of how FP is mostly an academic exercise, while OOP is used far more in the real world
Develliot
Develliot3y ago
I don't agree that just because something is old and everywhere it's good, ...wordpress. I'm also not telling you to do anything. I have clearly upset you and I apologize.
benten
bentenOP3y ago
It’s ok I’m more just ranting in general I rarely use OOP myself in JS but it does have its uses, despite YouTubers saying you should never use it Sorry I didn’t mean to vomit my anger on you lol
Develliot
Develliot3y ago
For me it's not so much about OOP it's about what is a natural fit for the language.
benten
bentenOP3y ago
I agree with you for the most part OOP kinda sucks in JS but it works fine for the most part for simple stuff
Develliot
Develliot3y ago
I sat through 30mins of that video and it was all stuff to do with scala that they have since fixed and then he goes on about why FP is awesome at the end. I take it you never watched the video I only shared my video because I knew it I saw it a few months back and wanted to share something cool.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Develliot
Develliot3y ago
See my comments above about closure and exports My point was that you don't need private/protected/public keywords anywhere in JS/TS and probably shouldn't use them It still winds me up that AWS CDK typescript is all class based, it drives me and my eslint config crazy. The point that you make about JS doing OOP and FP is the key. If you have a code base written in 2015 and it's all OOP you can incrementally fix that slowly over time. You can do a lot of stuff with JS and a lot of the pre es6 stuff can be an absolute foot gun. Which is why there are some bits that are best avoided.
benten
bentenOP3y ago
Just because you don't see a need for them doesn't mean they're useless for everyone always
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Develliot
Develliot3y ago
My argument isn't "you can do it without so you shouldn't" I've laid out all the reasons why I think they should be avoided above. For @SpeedDart We wouldn't be dealing with lexical scope issues of 'this' with JS/TS in 2022
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Develliot
Develliot3y ago
I'm saying there are problems when using old syntax like the one in the original question that is totally avoidable by avoiding the old syntax.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Develliot
Develliot3y ago
Classes come from ES6 you couldn't use it before then it's a post 2015 thing It's how we were writing react components back in 2017 with react 16.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Develliot
Develliot3y ago
The only use case I can think of for class components are error boundaries, you can't rely on them if you do SSR though. But that is it.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Develliot
Develliot3y ago
I will have to politely disagree and leave it at that.
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Wagner
Wagner3y ago
what an unusual topic, arrow functions are perfectly legible, and in fact make code more legible and clean in several ways. for example: - one liners - implicit return
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Wagner
Wagner3y ago
I'm talking about the comments from the OP, at the top of the thread
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
benten
bentenOP3y ago
I think arrow functions are less readable and I don’t use them at the top level. Of course they have their uses.
Want results from more Discord servers?
Add your server