17 private links
JavaScript function hoisting by example
Below are many examples of function hoisting behavior in JavaScript. Ones marked as works successfuly print 'hi!' without errors.
To play around with these examples (recommended) clone them with git and execute them with e.g. node a.js
Notes on hoisting
(I may be using incorrect terms below, please forgive me)
When JS is parsed, a first pass is done over each scope, and function definitions are immediately discovered. An example of a function definition is function foo() {}. When a function is declared like this, with a name, that name becomes available to the entire scope when the code in that scope is executed.
A crude timeline of how JS gets executed:
Parse the scope and detect all function definitions
Execute the code top-to-bottom with all functions found in step 1 available as variables
This behavior is called 'hoisting' because it is almost like the function definitions have been 'hoisted' up to the top of the function.
Assignments are not evaluated until the code is executed. An example of an assignment is var foo = function() {} or var foo = function foo() {}. A function must not be associated with an assignment in order for it to be hoisted (see example L)
Wrapping a function in parenthesis (()) is a quick way to convert a function definition into a function expression, which means it does not get hoisted (similar to assigning the function to a variable). I personally do not use this pattern regularly as I find it overly confusing to newbies etc, but I have included it because it is widely used in e.g. jQuery plugins.
I use hoisting as a code organization tool, for example here I rely on hoisting to make parseStream() available on line 20, even though it is defined on line 41, which I think makes that file more readable as I can put the 'meat' of the function at the top.
Callbacks are just the name of a convention for using JavaScript functions. There isn't a special thing called a 'callback' in the JavaScript language, it's just a convention. Instead of immediately returning some result like most functions, functions that use callbacks take some time to produce a result. The word 'asynchronous', aka 'async' just means 'takes some time' or 'happens in the future, not right now'. Usually callbacks are only used when doing I/O, e.g. downloading things, reading files, talking to databases, etc.
Summary
- Don't nest functions. Give them names and place them at the top level of your program
- Use function hoisting to your advantage to move functions 'below the fold'
- Handle every single error in every one of your callbacks. Use a linter like standard to help you with this.
- Create reusable functions and place them in a module to reduce the cognitive load required to understand your code. Splitting your code into small pieces like this also helps you handle errors, write tests, forces you to create a stable and documented public API for your code, and helps with refactoring.
The most important aspect of avoiding callback hell is moving functions out of the way so that the programs flow can be more easily understood without newcomers having to wade through all the detail of the functions to get to the meat of what the program is trying to do.
You can start by moving the functions to the bottom of the file, then graduate to moving them into another file that you load in using a relative require like require('./photo-helpers.js') and then finally move them into a standalone module like require('image-resize').
Here are some rules of thumb when creating a module:
- Start by moving repeatedly used code into a function
- When your function (or a group of functions related to the same theme) get big enough, move them into another file and expose them using module.exports. You can load this using a relative require
- If you have some code that can be used across multiple projects give it it's own readme, tests and package.json and publish it to github and npm. There are too many awesome benefits to this specific approach to list here!
- A good module is small and focuses on one problem
- Individual files in a module should not be longer than around 150 lines of JavaScript
- A module shouldn't have more than one level of nested folders full of JavaScript files. If it does, it is probably doing too many things
- Ask more experienced coders you know to show you examples of good modules until you have a good idea of what they look like. If it takes more than a few minutes to understand what is happening, it probably isn't a very good module.
More reading
Try reading my longer introduction to callbacks, or try out some of the nodeschool tutorials.
Also check out the browserify-handbook for examples of writing modular code.
What about promises/generators/ES6 etc?
Before looking at more advanced solutions, remember that callbacks are a fundamental part of JavaScript (since they are just functions) and you should learn how to read and write them before moving on to more advanced language features, since they all depend on an understanding of callbacks. If you can't yet write maintainable callback code, keep working at it!
If you really want your async code to read top-to-bottom, there are some fancy things you can try. Note that these may introduce performance and/or cross platform runtime compatibility issues, so make sure to do your research.
Promises are a way to write async code that still appears as though it is executing in a top-down way, and handles more types of errors due to encouraged use of try/catch style error handling.
Generators let you 'pause' individual functions without pausing the state of the whole program, which at the cost of slightly more complex to understand code lets your async code appear to execute in a top-down fashion. Check out watt for an example of this approach.
Async functions are a proposed ES7 feature that will further wrap generators and promises in a higher level syntax. Check them out if that sounds interesting to you.
Personally I use callbacks for 90% of the async code I write and when things get complicated I bring in something like run-parallel or run-series. I don't think callbacks vs promises vs whatever else really make a difference for me, the biggest impact comes from keeping code simple, not nested and split up into small modules.
Regardless of the method you choose, always handle every error and keep your code simple.
Remember, only you can prevent callback hell and forest fires
You can find the source for this on github.
We are a ground-breaking crossmedia distributor, building new revenue models for film, games, books and music. Our special event Bundles, focused on the best in indie culture, reach digital native customers all over the world.
We bring together creators looking for an effective way to distribute their work with a passionate community of customers eager to engage independent content. Our special event bundles are time-limited, themed and often curated by well-known names.
Right now we're working on a new product, Black Box, which will be launched later this year. Stay tuned for more..
WolfeOnDemand is the global LGBT movie-watching platform. The premium destination for all the best lesbian, gay, bi and transgender movies — available for streaming and download worldwide — WolfeOnDemand is powered by Vimeo and offers the highest quality viewing experience for movie lovers everywhere. Most titles come in deluxe editions complete with exclusive extra bonus features.
WolfeOnDemand is brought to you by Wolfe. Serving customers since 1985, Wolfe is the largest exclusive distributor of LGBT films. Explore WolfeOnDemand.com now and discover the world of LGBT cinema.
Browserify lets you require('modules') in the browser by bundling up all of your dependencies.
sudo cp -rp /home/my_home /media/backup/my_home
From cp manpage:
-p same as --preserve=mode,ownership,timestamps
--preserve[=ATTR_LIST]
preserve the specified attributes (default: mode,ownership,timestamps),
if possible additional attributes: context, links, xattr, all
Awesome CV is LaTeX template for a CV(Curriculum Vitae), Résumé or Cover Letter inspired by Fancy CV. It is easy to customize your own template, especially since it is really written by a clean, semantic markup.
TeX Live is an "easy way to get up and running with the TeX document production system. It provides a comprehensive TeX system with binaries for most flavors of Unix, including GNU/Linux, and also Windows. It includes all the major TeX-related programs, macro packages, and fonts that are free software, including support for many languages around the world."
TeX Live is one of the most popular distributions for LaTeX, ConTeXt and friends.
A Dcntralizd and Fdratd Social Ntwork
Oulipo.social is a lipogrammatic Mastodon for all.
- Marc Ribot - guitar
- Roy Campbell - trumpet, pocket trumpet
- Henry Grimes - bass
- Chad Taylor - drums
Dedicated to the music of Albert Ayler
One issue that is unfortunately contentious these days is whether denying Nazis a platform to organize and recruit by banning them from online spaces and university campuses (hereafter “No Platform”) is a violation of free speech principles. I say “unfortunately”, because it is hard to believe that we are actually having this discussion: of course it is not a violation of free speech principles to prevent evil people from organizing to commit genocide. But even if it were, we would still be morally obligated to so prevent them.
No platform is the practice of of preventing someone—either through policy or through protest—from spreading their ideas through a particular event or website. The term is mostly used to refer to rescinding an invitation to someone asked to speak at an event (such as a guest lecture at a college). The concept apparently originates from a policy used by the British National Union of Students to prevent people they disagree with from giving speeches on UK college campuses. The concept is similar to the political action of cordon sanitaire, where a politician or political party is either unconditionally excluded from coalitions or other forms or cooperation, or even completely ignored. "No platform" is typically invoked for issues such as racism, sexism, homophobia, Holocaust denial, and so forth. As what is and is not acceptable by society changes with the times, so do the targets of "no platform", with 2015 seeing protests of speakers seen as transphobic or Islamophobic who consider themselves progressive as they are feminists or atheists, respectively. No-platforming is, at best, an attempt to prevent a balance fallacy, with protesters refusing to allow tacit endorsement of reactionary views.
Depending on the circumstances, the tactic can be controversial, and has been compared to book burning.[1] Ignoring a person (or group) also means that no one is directly refuting their arguments. Some have criticized the action as a form of censorship and a violation of the principles of freedom of speech and critical thinking. The Foundation for Individual Rights in Education maintains a database of hundreds of incidents[2] in which invited speakers have been no-platformed on college campuses, showing that the phenomenon has been "steadily increasing over the past 15 years" and is used more often by left-wingers than right wingers.[3]
Advocates of no-platforming counter that the speaker's message has already been heard by protesters and venue holders, and they have decided not to extend the speakers the right to an audience that has already rejected them. The protests are generally meant to raise awareness of the target's views and not a call to place a blanket ban them; the reaction from many protested is arguably censorial itself, considering they're refusing to acknowledge the right to demonstrate opposition to their views.[4] Apparently, they believe that their speech is more free than others'.
De passage à une grand messe technologique comme l'ensemble du globe et la place parisienne en comptent tant et tant, le président Emmanuel Macron a récemment déclaré : "Je veux que la France soit une Start-Up Nation. Une nation qui...
Composer and sound artist, guitar and objects player, silence listener.