Nitpick: let is a statement. Assignment/binding is an expression. That is why let x = y = 42; works. x = 42 evaluates to 42 as does x = y = 42
.
Global scope is like setting some variables at the top of your file.
There is a global object that is available via the "global scope" but that is pretty much the extent of the "global scope". No new global names can be created. It just seems that way because properties on the global object can be directly accessed without referencing them through the global object - that is why they seem to exist in the "global scope". So if you need to access new names globally then you need to add them to the global object as properties.
Global objects: window (browser window), self (browser window and web worker), global (Node.js), globalThis (evergreen browser windows, web workers and Node.js (12.0+)).
The issue is that script level (outside of functions) var declarations inside of inline scripts (type="text/javascript", not type="module") attach themselves as properties to the global object. That doesn't happen inside functions, module scripts and ECMAScript modules.
import names are completely hoisted throughout that module ("module-global") but that doesn't affect other modules.
If you squint you can see the similarities. Hence quote:
Objects are merely a poor man's closures.
Closures are a poor man's object.
You can use a closure like an implicit object.
There is another difference
That difference (their this being bound to the this of their site of creation rather than being dynamically set at run time based on the manner of invocation) is the reason why arrow functions were introduced in the first place.
Again, this is not the ultimate solution as it will only assign the parameters in order.
You can use a default parameter by deliberately passing undefined.
filter is a method of the Array instance (Array.prototype.filter()). But it doesn't use searchQuery. filter is a higher order function (HOF) - i.e. it is passed a function value as an argument, in this case (post) => post.includes(searchQuery). It's that argument (function value) that accesses searchQuery via the closure it (the function value) was created in.
The fact that searchQuery is outside the scope of filter is irrelevant as filter only uses the passed function value. It's the passed function value that accesses searchQuery outside of its own function scope but inside its closure.
You can use the declared function name directly for filter - no need to create another intermediate arrow function.
constblogPosts=['Just Graduated a Boot Camp!','What is a Stack?','Growth Mindsets: A Fever Dream?','Working at FAANG! An Ex-FAANG Tale','Working at a Startup! An Ex-CEO Tale',];constsearchQuery='Ex';console.log(blogPosts.filter(findPostByQuery));/* ["Working at FAANG! An Ex-FAANG Tale",
"Working at a Startup! An Ex-CEO Tale"];
*/functionfindPostByQuery(post){returnpost.includes(searchQuery);}
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Nitpick:
let
is a statement. Assignment/binding is an expression. That is whylet x = y = 42;
works.x = 42
evaluates to42
as doesx = y = 42
.
global
(Node.js), globalThis (evergreen browser windows, web workers and Node.js (12.0+)).var
declarations inside of inline scripts (type="text/javascript"
, nottype="module"
) attach themselves as properties to the global object. That doesn't happen inside functions, module scripts and ECMAScript modules.import
names are completely hoisted throughout that module ("module-global") but that doesn't affect other modules.While true in your particular example that isn't the full story as you explore in your Chapter 3 bonus.
Given the right circumstances the local variables of that particular invocation will continue to exist inside the closure.
Compare this to
If you squint you can see the similarities. Hence quote:
You can use a closure like an implicit object.
That difference (their
this
being bound to thethis
of their site of creation rather than being dynamically set at run time based on the manner of invocation) is the reason why arrow functions were introduced in the first place.You can use a default parameter by deliberately passing
undefined
.null
doesn't work as it is considered an intentional value.The two types that people actually get hot and bothered about are "synchronous" vs. "asynchronous" (i.e. returns a promise)
Professor Frisby's Mostly Adequate Guide to Functional Programming - Chapter 03: Pure Happiness with Pure Functions:
A pure function is free to call other pure functions.
Functional Geekery Episode 08 - Jessica Kerr isolation:
Probably was supposed to be
more like
This property is referred to as referential transparency.
… so that a function invocation with a specific set of arguments can be simply replaced with its return value.
See Functional Core - Imperative Shell (related to Hexagonal Architecture).
Is that what you mean?
filter
is a method of the Array instance (Array.prototype.filter()). But it doesn't usesearchQuery
.filter
is a higher order function (HOF) - i.e. it is passed a function value as an argument, in this case(post) => post.includes(searchQuery)
. It's that argument (function value) that accessessearchQuery
via the closure it (the function value) was created in.The fact that
searchQuery
is outside the scope offilter
is irrelevant asfilter
only uses the passed function value. It's the passed function value that accessessearchQuery
outside of its own function scope but inside its closure.You can use the declared function name directly for
filter
- no need to create another intermediate arrow function.