38
u/damnNamesAreTaken Apr 14 '24
As someone who doesn't really use JavaScript much, what was wrong with the function declaration form and why are the rest needed? I learned JS before the newer ways existed and never really kept up.
82
u/travybongos69 Apr 14 '24
Arrow functions don't have their own
thiswhich can be useful at times10
2
u/Think_Discipline_90 Apr 15 '24
"At times" try 99% of cases.
The only times I use oldschool function declaration is if I want typed overloads
3
Apr 15 '24 edited Apr 14 '26
Data Brokers don't stand a chance because I mass delete all of my content using Redact - No AI training on my data, thank you very much.
cooing punch encouraging fuzzy longing squash bright fact thought lock
30
u/joelangeway Apr 14 '24
When
functionis a statement, it has the same binding rules asvar. When it is an expression, a name is optional but if it is provided it is scoped to the function body. The fat arrow operator is just like afunctionexpression accept it does.bind(this)at the end and can have an expression instead of a code block for a body.JavaScript has a lot of warts, but the way it lets one sling functions around …. I just love it.
8
u/SparserLogic Apr 14 '24
They are handled differently by the compiler when it comes to where the function is scoped in memory. Variables are treated like other variables rather than globally like a traditional function.
5
u/RaveMittens Apr 14 '24
the compiler
The interpreter?
5
u/MaxUumen Apr 14 '24
The engine
3
u/RaveMittens Apr 14 '24
The runtime
26
u/SparserLogic Apr 14 '24
The thing that does the thing.
2
3
4
u/armano2 Apr 14 '24
its actually a compiler, compilation is usually done "before" execution, but technically this is still a compilation
read more. https://v8.dev/blog/background-compilation
1
u/shitty_mcfucklestick Apr 15 '24
A series of short gasps were heard, and the room fell silent as all eyes turned to /u/SparserLogic. Did they really know JavaScript, or are they an undercover desktop C programmer person trying to infiltrate the sub?
Tune in next Friday!
2
1
u/eruwinuvatar Apr 14 '24
The function expressions can be inlined (you define them where they are used) and if you are going to inline them anyway, it's better to be as concise or as short as possible:
const sumOfSquaresOfEvens = nums .filter(x => x % 2 === 0) .map(x => x * x) .reduce((x, y) => x + y)You could declare those 3 functions beforehand but what's the point in declaring one-liner functions?
2
u/ravepeacefully Apr 15 '24
Testing, readability, reducing complexity overall
1
u/nodeymcdev Apr 16 '24
I’m sure you meant the opposite of what I’m about to say but declaring three functions is generally much more complex and less readable than just chaining array methods
1
u/ravepeacefully Apr 16 '24
No. Functions should be as small as possible.
I get what you mean, it’s totally appropriate for VERY simple operations to be chained, but overall functions should be as short and simple as possible.
You should absolutely not have 120 line functions that carry out a multitude of operations.
1
u/nodeymcdev Apr 16 '24
Of course it depends on the situation, but if the function is only being used in that one place it makes sense that it’s not defined but just written inside of a chained array method. Otherwise you’re forced to jump around a file searching for functions by name. Much more readable to just start at the variable name “sumOfSquaresOfEvens” and read what it does where it’s doing it.
1
u/ravepeacefully Apr 16 '24
So what you’re saying is you don’t write tests?
1
u/nodeymcdev Apr 16 '24
Of course I do. I split up my code into functions where it makes sense to do so. sumOfSquaresOfEvens is a simple function. In this case you aren’t going to test each individual method inside of the chain. You are going to test the entire thing together.
1
u/ravepeacefully Apr 16 '24
Ya that seems reasonable.
But that’s not what the original post was suggesting, it had an inline sumOfSquaresOfEvens.
If that is inline, I’m gonna go ahead and assume the containing function is unacceptably complex. The poster asked why that function should be broken out as opposed to inlined and I suggested for testing and readability.
I guess it would be ok to just slam in a bunch of inline functions and test the inputs outputs depending on your requirements, but typically I’m not writing code with the intention of it being used in only one place. Inevitably this leads to an unmanageable mess.
What happens when we switch the algorithm for calculating the number? You go and change that inline function all over your code? Na
1
u/nodeymcdev Apr 16 '24
Right it definitely depends on the situation and if the code is used in multiple places then breaking it out into functions isn’t just good practice it’s a necessity.
-1
-11
u/azhder Apr 14 '24
If what you say is correct (I highly doubt), you have learnt JavaScript in the 90s.
The function declaration is hoisted and doesn’t even respect blocks like
if-elseif you happen to forget and put the same name in both paths.5
u/damnNamesAreTaken Apr 14 '24
What are you telling me I'm incorrect about? The arrow function wasn't a thing until around ten years ago. I almost never use JavaScript so I never kept up on what the true differences were other than syntax. I learned JS in the mid 2000s.
-15
u/azhder Apr 14 '24 edited Apr 14 '24
I didn’t say you are incorrect, I said I doubt you have learnt it in the 90s. The function expression existed at least in the ES3 standard, released by the end of 1999.
10
u/realboabab Apr 14 '24
you are doing a really poor job of communicating here..
-12
u/azhder Apr 14 '24
Good for you that you noticed and voiced the concern. There’s still hope for the internet.
Do not read it in a sarcastic manner.
2
u/wherewereat Apr 14 '24
You placed the comma after the parenthesis, suggesting that the sentence betweeen the parenthesis is referring to the first statement.. Then a comment later you explained that the parenthesis sentence is referring to the sentence after it, but that doesn't make sense when there's a comma right after it. so in other words, you're doing a poor job of communication
-3
u/azhder Apr 15 '24 edited Apr 15 '24
So far you haven’t told me anything I don’t know…
Well, you did tell me one thing: you thought you should respond to me.
So, I might as well ask you: why?
Oh, and you told me you think I made a mistake… I didn’t, but requires closer inspection and deconstruction than what you did.
The comma wasn’t misplaced, but you may have read those verbs a bit differently
2
u/wherewereat Apr 15 '24
I thought you were thanking the other guy sarcastically, I just read the second part rn, guess I'm in the wrong here ,_,
-1
u/azhder Apr 15 '24
You know, the way I write responses, it often has a secondary use. But that’s a topic for another time.
→ More replies (0)1
u/Shaper_pmp Apr 15 '24
I didn’t say you are incorrect, I said I doubt you have learnt it in the 90s.
Dude, there are some of us here who wrote our first JS in Netscape Navigator 2.0beta in 1995.
JS was also orders of magnitude simpler for years before widespread support for Msxml2.XMLHTTP/XMLHTTPRequest made it feasible to even start writing complicated client-side applications in the mid 2000s, so lacking huge, modular codebases there was basically zero concern about things like restricting scoping or polluting the global scope.
If someone wrote JS early in their career and then didn't really stay up to date, it's not at all surprising that they might remember function definitions, but not really comprehend the point of even function expressions, let alone things like arrow-syntax.
3
2
u/Soft-Sandwich-2499 Apr 14 '24
!remindme 6h
1
u/RemindMeBot Apr 14 '24
I will be messaging you in 6 hours on 2024-04-15 02:44:41 UTC to remind you of this link
CLICK THIS LINK to send a PM to also be reminded and to reduce spam.
Parent commenter can delete this message to hide from others.
Info Custom Your Reminders Feedback
1
0
u/Freecelebritypics Apr 14 '24
NGL two seems illegal
2
u/n8rzz Apr 15 '24
Why do you say that? Genuinely curious.
1
u/Freecelebritypics Apr 15 '24
I am a total amateur so feel free to ignore me! I just don't know why I'd ever need to write function AND const on the same line.
2
u/Studnicky Apr 15 '24
It's for keeping your code clean while using anonymous functions with libraries that require callbacks. Makes it much easier to read than a stacked mess of indents and brackets.
1
u/n8rzz Apr 15 '24
One reason this may be useful is because it prevents hoisting. A second reason is that you could conditionally assign a function to a variable for use later. A third, though not as common today, is it allows you to extend a function by adding more functions to its prototype. You rarely see this today because we have classes. But that’s how we’d fake classes years ago.
2
u/Freecelebritypics Apr 15 '24
I've certainly used the second scenario before, now you mention it. Though I haven't found a situation where I'd want to prevent hoisting yet.
And yeah, proper classes have been around since I start learning JS.
Thanks for the explanation.
2
0
-5
-1
u/SponsoredByMLGMtnDew Apr 14 '24
I don't think I would've used arrow functions as the final two ways.
Definitely would've gone with partial application
let __map = [].map;
function map (list, unaryFn) {
return __map.call(list, unaryFn);
};
function square (n) {
return n * n;
};
map([1, 2, 3], square);and currying
function curry (binaryFn) {
return function (firstArg) {
return function (secondArg) {
return binaryFn(firstArg, secondArg);
};
};
};
let curriedMap = curry(map),
double = function (n) { return n + n; };
let oneToThreeEach = curriedMap([1, 2, 3]);
oneToThreeEach(square);
//=> [1, 4, 9]
oneToThreeEach(double);
//=> [2, 4, 6]I don't think I would've used arrow functions as the final two ways.
0
9
Apr 14 '24
[removed] — view removed comment
33
u/Formally-Fresh Apr 14 '24
Well the title does specify “4 ways” not “every way”
8
8
u/BenjiSponge Apr 14 '24
The function expressions are all anonymous, but then they're given a name afterward.
Consider
function hof(fn) { setTimeout(() => console.log(fn(5)), 1000); } hof(x => x * x);You could argue that this is "more anonymous", but it's also assigned into a variable called
fn. It's no less or more anonymous thanconst square = x => x * x;.You could maybe use an IIFE to be "truly anonymous", but... this is just splitting hairs really. Any function expression is an anonymous function.
11
u/jwalton78 Apr 14 '24
There are actually subtle differences between assigning a function to a variable and passing an anonymous function as a parameter. Assigning a function directly to a variable gives it a
name(and the definition of an anonymous function is one that doesn't have a name):function showName(x) { console.log(x.name) }; // Prints "square", because square is not in fact an anonymous function. const square = (x) => x * x; showName(square); // Prints "", because this is an anonymous function. showName((x) => x * x);3
u/BenjiSponge Apr 14 '24
Huh, didn't know that! Thanks for the info.
2
u/azhder Apr 14 '24
It’s an engine optimization.
It didn’t always do that and the difference can be seen if you do this:
const notTheName = function theActiualName(){};1
u/azhder Apr 14 '24
I wouldn’t say they are given a name afterwards (although newer engines are smart to do so), but I would say a variable with certain name holds a reference to it.
1
u/rover_G Apr 14 '24
The arrow functions also don’t have a prototype. What that actually means I’m not sure.
1
1
1
31
u/Shaper_pmp Apr 14 '24 edited Apr 15 '24
Five ways:
new Function('x', 'return x * x');Six if you include defining class methods using the
classsyntax, but there's no way I can think of toreturna raw value from a constructor (not even with hacks like overridingvalueOf), so it's not strictly the same as defining a plain function that takes a parameter and returns a raw value.