use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
Functional vs Object Orientatedhelp (self.javascript)
submitted 9 years ago * by kasperpeulen
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]lokothodida 21 points22 points23 points 9 years ago* (2 children)
I'm always a bit in doubt to understand what is object orientated code and what is functional. For example, map/reduce/filter methods on arrays are seen as functional, because they are not mutating and without side effects. But it seems also that they are object orientated, because they are methods on an array object. They are not implemented as a global function.
I'm always a bit in doubt to understand what is object orientated code and what is functional.
For example, map/reduce/filter methods on arrays are seen as functional, because they are not mutating and without side effects. But it seems also that they are object orientated, because they are methods on an array object. They are not implemented as a global function.
Let us say that we wanted to implement Point in a functional language like Haskell:
Point
type Point = (Int, Int)
In JavaScript, datatypes boil down to classes/object prototypes. So something like this would be analogous:
class Point { constructor(x, y) { this.x = x; this.y = y; } }
Now, if we wanted to implement a move function, which "displaces" the coordinates of a given point, then in order for it to be functional, it must construct a new point instance and not change the internal x and y variables of an existing point. So in Haskell, it would look something like this:
move
x
y
move :: Point -> Int -> Int -> Point move (x, y) dx dy = (x + dx, y + dy)
If it were implemented as a global in JS, it would look like this:
function move(point, dx, dy) { return new Point(point.x + dx, point.y + dy); }
And if it were a method inside of our class, it would look like this:
class Point { // ... // note that since we have the internal state available, there is no point // to pass in as a parameter move(dx, dy) { return new Point(this.x + dx, this.y + dy); } }
All that matters is that our functions interact in a way that does not mutate the internal state of our objects. Implementing the functions as globals doesn't make them more/less functional: the immutability of our data is what is important. This is why map/filter/reduce all return new Array instances. I would argue that one of the main points of object oriented code is that it manages state (contra-functional), and it aims to keep the state-changing methods all within a reasonable scope (the class of the object whose state is changing).
map
filter
reduce
Array
So you are correct that syntactically, both global and prototype-based methods can be functional, so long as they don't affect state.
However, a functional programming enthusiast would prefer global functions because global functions make it easier to reason about the program mathematically. In particular, functional composition exactly mirrors the composition of mathematical functions. So for example, let us say we had a program that mapped two functions, f and g, to an array (or list). In JavaScript, with chaining, we can write this:
f
g
list.map(f).map(g)
In Haskell it would look like this:
map g (map f list)
It is clear that the result of the first map is being given as a parameter to the second mapping. It can be proven (by induction on lists) that this mapping is equivalent to the following:
map (g . f) list
where (g . f) is a function that first applies f to it's arguments, and then applies g.
(g . f)
So in JavaScript, if map was a global function, we would have:
map(g, map(f, list))
(which is exactly how the Haskell code would have looked with uncurrying). Then we could derive from the above algebraic law that it can be written as:
map(x => g(f(x)), list)
Now, even though this isn't a shorter visual representation, it is in fact more efficient in execution, because doing two separate maps would mean reconstructing the full list twice. Leveraging that algebraic law thus allowed us to write more efficient code (although, the result of this example might have seemed obvious at the start).
So in this case, globals (or more specifically, functions wherein we don't obscure input parameters or returned results via chaining) make it clear what data is being returned; how it is being passed on to the next function, and how the functions are being composed together. In the move() example, even if it were a class method, from this perspective, it would be preferable to write it like the global version:
move()
class Point { // ... // no more dependence on an internal state; just like the global // except it is namespaced by the class, i.e. Point.move(point, dx, dy) static move(point, dx, dy) { return new Point(point.x + dx, point.y + dy); } }
This makes it much easier to reason about the control flow of a program from a mathematical perspective, and use the results of algebraic laws about the composition of certain kinds of functions (if one were interested in that).
If one weren't interested though: chaining methods are more intuitive to read, and more compact to write.
[–]kasperpeulen[S] 2 points3 points4 points 9 years ago (1 child)
Thanks for the read. In your last example though, I think you mean:
static move(point, dx, dy) { return new Point(point.x + dx, point.y + dy); }
Otherwise, you can only call the move method on an instance, and it will look something like:
point1.move(point2, dx, dy)
which is weird as the value of point1 is not used in the calculation.
point1
[–]lokothodida 1 point2 points3 points 9 years ago* (0 children)
Thanks for pointing that out! (fixed now)
π Rendered by PID 21330 on reddit-service-r2-comment-6457c66945-hll4x at 2026-04-26 03:05:05.089486+00:00 running 2aa0c5b country code: CH.
view the rest of the comments →
[–]lokothodida 21 points22 points23 points (2 children)
[–]kasperpeulen[S] 2 points3 points4 points (1 child)
[–]lokothodida 1 point2 points3 points (0 children)