function vs method
Anyone know of a good guide that explains the difference between a function and a method? I don't really understand when one should be used over another since, if I'm not mistaken, they're both functions at a base level.
159 Replies
I don't know of any guides about this (also am interested if someone finds one), but I can answer your question by saying the words "Function" and "method" are used pretty interchangably in the javascript ecocsytem.
You could argue "method" refers to a "function which belongs to something (e.g. a
class
or other object)".
But in the end all methods are functions, though with the above argument not all functions are methods.You could argue "method" refers to a "function which belongs to something (e.g. a class or other object)".This was my understanding, although I didn't think it could be that simple (nothing in programming is!) The main thing that kinda threw me off was args in relations to methods, I may have just not searched enough but can you have a method with args? Something like
thing.method(arg1, arg2)
?Yep
So in your case
thing
might look like this:
which could just as easily be written like this:
For like 99.99999% of use cases those are identical.
Where 'method' really comes into play is with class
es and this
.
is different from the following:
(i'm like 60% sure about that, this
is confusing af and I work professionally in JS-land)
A general rule of thumb I follow is: "If this ever matters, you should restructure your code so that it no longer matters" 😅This sounds like great advice! So
this
in the first example just points to the object/class the method is in? So is this.otherMethod()
effectively method.otherMethod()
or Thing.otherMethod()
?I get better every time I explain this give me a sec
this
in the first example is 'effectively'* Thing.otherMethod()
* big caveat.
this
is "this instance of Thing
", where the syntax Thing.otherMethod
would call a static
method named otherMethod
on that class.
A method
could be defined as a function
which is a 'property' of another .... thing. In this case a class
.
confidence hovering around 80% for that example
I've never tried having the same named things in a class but some static and some notOK, I've wrapped my head around that... just about. The only thing I don't get is why
Thing.bar()
and new Thing().bar()
call different things. My understanding is that ()
is used on classes for constructors?
I think I'm a bit out of my depth here 😅gonna be honest that's the part I'm not super confident about. it might be that both call the static
bar
new Thing()
instantiates the class. Way to think about that is "Thing" may be a generic template, but when you instantiate it you get one unique thing.
We're pretty far off course from your original question and firmly in the weeds of "Object oriented javascript".
I do know of a good walkthrough of that topic:
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS
I want to stress though that you can get by perfectly fine without a deep understanding of all the nuance here.
(I certainly do lol)I imagine you can, but I'm very much someone who learns how something works by knowing all the moving parts, and then forming my own mental "map" of how it all works. I'll take a look at that guide though, seems useful. Thanks for your help!
@lebombjames1 gave LeaguePoints™ to @calego (#1 • 1175)
I personally like to think of
this
as a tool to help you get the current class. If you're writing it in a static function you'll get a reference to Foo
and if you're writing it in a method of a class you'll get a reference to the current instance like new Foo();
You can see that in the example there;
console.log(new Foo());
and console.log((new Foo()).method())
look identical (non-static method). Same with console.log(Foo);
and console.log(Foo.method());
(static method example).
This is how this
or similar constructs in other languages is known to function, Python might call it self
but they're pretty similar. The reason why it's useful is because it lets you do something like change the current class/class instance without having to refer to it by name or something messy....
That might be a bit abstract but that's how I think of this 95% of the time.
Javascript decided to make things more confusing by making this
usable in all sorts of other contexts where it's rarely as useful. Also all sorts of exceptions and ways to change its behaviour with stuff like bind
that quickly devolves into complex.
TLDR of my long writing:
The context where it's cleanest, this
means this class. Say you have Foo
with a method using this. When this method is static it refers to Foo
when it's non-static it refers to the "instance" the "current" Foo
that you make like new Foo();
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
This is pretty similar to how I explained it in DMs to Calego.
The rules for how this make sense if you know how call and bind work because this is still missing arrow functions.
and that everything is an object
and about implicit accessing on
window
/globalThis
in non-strict mode... and that arrow functions are essentially wrappers around bind and...
it's confusing
because you have to know how the language is doing things
and you don't know that at the basis.
other languages keep this
in a much more narrow context so you don't have to go explaining about how function calls goes to the call
method and the signature of the call method or really the [[ Call ]]
or whatever it is internally I don't recall off the top of my head
You don't have to know that classes are actually just functions which are actually just objects so static and non-static make sense... in short you don't have to know much about the internals of this
in other language equivalents
you just know this
= this class's current instance in non-static context or this class in static context.
it's not that there aren't consistent rules being applied here it's that you have to be comfortable with the concept of drain away a not small amount of wrappers around the object oriented core. I explained it in class concept because that's A) Transferable to other languages B) Constrained in the context where this
as a keyword is most generally used.
Seeing someone plop this in a random object is mostly just confusing for people in my experience even if I know what's going onUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
I know
I know it's not magic
the point was in that sentence that you have to get what bind is
not that arrow functions are some entirely new concept
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
python has everything as objects ultimately and still manages by having
self
be passed as the first parameter to methods
And it's not "hiding the truth of the language" more so that following the rules to get down to the actual call method is confusing for people who don't know "the truth of the language" which is a huge scopeUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
I was trying to answer without using any of those words because the thread title is
function vs method
if I could use half of those words I think they'd not have had the questionUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
They did.
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
By not binding this strictly to class methods
It adds confusion in the greater scheme as to how other languages do it
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I just said why it's different to Python
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
but not outside, you can use
this
in the global scope
or in an objectUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
or elsewhere
in js ofc
not self
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I'm know there's binding. Javascript does it eagerly which gives a difference:
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
This example is in the global scope.
this
also contains static methods, static are added implicitlyUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
which is another difference from how it works elsewhere
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
My point is these are differences that are confusing when you try to do a comparison to other languages because Python keeps it contextually narrow.
That's the same as Javascript, yes.
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I have understood that
for the entire time
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
because Javascript has these differences
A) Globally available outside of methods; binding is implicit
B) Static prototype copied over
C) Binding terminology implies an understanding already of what call contexts, object oriented programming etc. it
These differences from other language constructs are not something that is transferable knowledge or particularly intuitive for a non-insignificant amount of people. Keeping
this
in the context of class methods is transferable.Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I give up on A and B
.
Self is bound strictly within methods as a parameter for you
global scope is A
this is in the global scope
it's everwhere
I feel like you had a rebuttal I don't understand
I said it again
you will gave same rebuttal
circular
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yes but not globally as in the global scope
self isn't just a "magic" thing that appears
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Right but they're separate for a reason.
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
It's less flexible but I can hardly think of the last time where I thought something like
this.addEventListener()
or this.x
is more clear than just elem.addEventListener
or obj.x
There's names for a reasonUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
Or... pass the elem or object as a parameter
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
so that you don't have to bind to change it if you call it where
context !== elem
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
my opinion is that
this
is a super user type feature and self
is one that can be summed up to someone who at least gets what functions are in about a minute
explaining this
requires explaining scopes, implicit scoping in non-strict mode, etc.
giving an incomplete answer to explain this
in the context that's most transferable and intuitive isn't as hard as explaining how to keep track of scopingUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
and the exceptions with functions that have been binded
it's a direct result of how bind/call work but like you have to know how they work
it's just a pile of explanation over explanation rather than
self = the current class instance
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
this = defaults to the the current context which call sets by default but arrow functions set to the defining context due to being syntatic sugar around (function () {}).bind(this)
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
a bit shorter with the same information
this = the current call context, set by default by .call but language constructs can change that
It's... not negligible to include arrow functionsUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yes it is
and it's not exactly something to sum up as easily as
self, first argument in a method = the current class instance
because self is less powerful
it's confusing to compare this
to self
because this
is basically a superset of the cases of self
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
You can't use self in static methods in python by default
you can write your own decorator to attach it ofc but
@staticmethod
doesn't have self
passedUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
Older Python might've done it this way in which case we're both right
but this is current
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yeah I'd have to install Python 2
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
probably
__init__
or something it spawns because __getattr__
would be too broad, I believeUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
I think they might duplicate
__dict__
anyways from the base class because otherwise one instance method would be able to effect anotherUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
point beside of the nitty gritty dunder method it is different in that it's only for instance methods
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Right I understand that I was under the impression that all that occured at
__init__
; they copy unbound methods onto the instance and make them bound methods.Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Maybe I'm misunderstanding, but if instances didn't copy the unbound methods this'd make foo.method == bar.method across the setter:
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Result:
Does that line up with what you meant?
few ways you could've meant
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Right I get what you're saying now, I thought it was missing the second step:
foo.method
-> foo.__dict__['method'](foo, ...)
if it's in the local dict then foo.__class__.__dict__['method'](foo, ...)
if it's not.Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Right
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Right which is sorta what I was trying to get across with the copying
even if it's not on a rudimentary copy like you're probably showing
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
lol probably some of the weirder code I've seen considering that there's implicit binding in javascript to provide this anyways but yes I suppose I can see that. Though you can inspect the class method and see it's not using the
@property
decorator used for proper getters in python, it is very close to oneUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
I get the gist, yeah
I suppose both of us was right in some facets depending on how Python 2 and Python 3 diverge.
Which probably lead to some of the confusion.
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Which is entirely fair
but that's the closest python code yes, so I suppose I take back the "not a getter" it's more of a... direct getter if that makes any sense?
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
right because
you're defining
bind
or even if you're not defining bind in this context
it's just way slowerUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yeah iirc bind was added in like ES5 anyways
not like functions weren't doing this before ES5
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I think bind actually uses
[[Call]]
iirc
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bindUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
yeah
It's basically, in pseudo code ofc
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yeah sorta like this
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
if Javascript were written in...
javascript
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
https://tc39.es/ecma262/multipage/ordinary-and-exotic-objects-behaviours.html#sec-boundfunctioncreate
Right just linking because there's a link to
BoundFunctionCreate
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
same info just without the stuff about safety checks
interestingly I just learned the term "exotic object"
I mean I knew the properties just not the term
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Right Python 2 does in fact sound more complicated and less internally consistent if you poke that far
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
but Python 3 at the least fixes that
I wonder why the Javascript designers decided the name
this
rather than self
just random idle thoughUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
self
has always felt more descriptive to meUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
Fair, though that just punts the question to whoever made the decision first
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I guess they just decided on that nomenclature over
self
because they probably didn't even think of it
and this
in JS was probably just taken from Java because of its origination of literally wanting to be "the easy Java"Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
and Java probably just took it from C++ lol
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
nonexistant?
JS from 1995, Perl from 1988
right?
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Fair
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
ugh I'm trying to find a designer's note
but both
self
and this
are horrible to search for
but I recall reading at one point one designer saying they could've made it implicit because it was reserved or something but didn't.Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
ugh lol
I've seen that type of code before
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yeahhhh... which works I guess, lol
Maybe flashing back to people without even mentioning it's trying to simulate a class
which is why the
ugh
is there
but it certainly looks less nice than higher level classes in my experience lolUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
oh I'd consider that if I ever did OOP in C
If I need the performance I generally just use Go or C++
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yeah I've been learning Rust a bit but since I tied it to one side project and also because I put aside that one side project...
I haven't been doing much Rust
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yeah
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I do have to say my only real complaint of what I saw of Rust is I think it has perhaps a bit too liberal usage on macros from the standpoint; for instance the core Rust code itself has a few examples where they'll just use a macro to fulfil a trait multiple times (literally... had to Google that because I forgot lol). It means the language probably isn't putting much effort in to keep the binary size down.
I love their
Box
memory explicitness, Result
, pattern matching, etc. thoughUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
oh cool
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Well I meant trait fulfilment but that too fair
A little bit of type erasure for simpler cases like
i8 + i16 + i32 + i64 + i128
could go a fairly long way to a better middle ground between both performance and binary size... it'd just be very hardUnknown User•4y ago
Message Not Public
Sign In & Join Server To View
oh? Okay I'll have to take another look.
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
In all fairness by default any compiling done should result in bigger binaries for faster execution anyways
since I think development wise you want an optimized binary like... at the end
you want to just run it like 95% of the time or more
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
but yeah I guess I might be referring to an already fixed problem
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
not bringing in the stdlib would make me irrationally sad
but yes
that would be the way you'd do it
(the stdlib is just very neat in Rust imo)
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Right.
One of the reasons I put aside my project, which was an implementation of a bunch of different statistical algorithms because I kept getting sick of finding absolutely no one that'd implement something like taking the Irwin–Hall distribution and making it closed form and discrete to get actually 100% accurate results... and like droves of people implementing brute force implementations with imprecise results. Like what's the probability distribution of
1d1000 * 1d(1d12)
I got through most of the calculations I wanted to do by hand, though that was never the focus anyways, then I found that my code was absolutely ballooning if I wanted to make my DSL able to intermix types more fluidly than Rust (because the DSL was just gonna be probability calculations and a cast at every step was annoying/impossible). And I found ways around it and crate options to try... but I quickly found that compiling was taking forever and the binary was huge for simple things and I finally stopped once I realised that the crate options I was using were subject to change.
You've given me a fair point to go back and actually see if they've fixed some of those things lol.Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Oh yeah I wouldn't have minded as much if the code weren't also massively finnicky.
Like you know those projects where you're almost there so you have to test and test and test your code?
well this was one of them and so I was compiling and recompiling lol
super small changes
super big differences
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
I'm pretty sure I turned it off and it was mostly the macros being really slow.
And making things not cacheable in this case
I bet there's improvements there
Unknown User•4y ago
Message Not Public
Sign In & Join Server To View
Yeah I'll look back into it. I might just... idk manually unmacroify them and then remacroify them when I'm fully done because the macros are way cleaner than files full of traits and stuff.