We were tasked with making a whack-a-mole game in Javascript today.
Here's what I came up with!
Tuesday, April 28, 2015
Monday, April 27, 2015
Whack-a-link
Just playing around with the Javascript that we learned today--
Enter this code:
https://gist.github.com/johnwquarles/357a51887dd72464ddbf
into your browser's Javascript console (and edit the source CSS if desired/necessary), and you can play whack-a-link with the page (links disappear when clicked, but will reappear after a few seconds).
Enter this code:
https://gist.github.com/johnwquarles/357a51887dd72464ddbf
into your browser's Javascript console (and edit the source CSS if desired/necessary), and you can play whack-a-link with the page (links disappear when clicked, but will reappear after a few seconds).
Sunday, April 26, 2015
Crockford's Concoction
Having worked through HTML and CSS (and many related frameworks/preprocessors), my cohort and I have arrived at what will presumably take up most of our class time going forward (since our backend framework is Node.JS): Javascript.
I just finished reading and doing all the exercises for A Smarter Way to Learn Javascript, so "document.getElementById()" and "function thisArbitraryFunction() {" are pretty well committed to muscle memory. I know that eyeballs are the only body parts that are supposed to move during REM sleep, but I wouldn't be surprised if my fingers are twitching those commands out during my dreams to come...
Anyway! How about some content?
As part of our "homework" we have been watching Douglas Crockford's "Crockford on Javascript" lecture series on Youtube. The first is a fascinating look through computer and programming language history up until Javascript, the second touches on the particulars and history of Javascript itself, while the third outlines strengths/peculiarities of what Crockford considers Javascript's greatest asset: its functions.
I'd like to consider some code presented toward the end of the lecture, which Crockford presents as a common mistake made by Javascript developers:
Crockford points out that in the top code, all event handlers created by the loop will report the same div_id (the last one) no matter which one is clicked, which is not the desired behavior. In the bottom code, however, each div_id is reported (alerted) correctly because the "make_handler" function is pulled outside of the loop. He tells us that this fixes the problem because of function closure.
Hmm.. I had to pause for a while and give this one some thought. Here's how I see it:
In the top loop, we've created some arbitrary number of event handlers. The loop makes them all at once, and after their respective geneses they all do their thing, handling events as event handlers are wont to do. Each handler is supposed to listen for clicks on a specific div, and alert their specific div when it's clicked.
Great, except that the "div_id = divs[i].id;" line occurs outside of the actual "divs[i].onclick = function () {" functions that are created. In other words, div_id exists outside of the generated functions' closures; like Python (and unlike Ruby unless you explicitly make a global or instance variable, afaik), functions are able to pull variables "above" them in scope in to use, but variables that are declared/reassigned within them are scoped to their respective function closures.
So what happens here is that we get event handler functions that each handle click events for their particular divs. They do this job admirably, but when the actual functions are called, they each alert a "div_id" variable that is pulled in into the function's scope from outside of it; "div_id" does not belong to the function's scope; it belongs to the scope that sits one level above each function.
In other words, each function pulls, from outside of its scope, the same "div_id" variable! And this "div_id" will point to the very last div that the iterator "i" iterates through in the "for" loop, since that's the last value that div_id is set to before the loop ends and we stop reassigning it. The loop runs its course, all the event handlers are created, and div_id winds up set to the very last value of divs[i]. Each individual event handler function now reaches outside of its scope to pull in and alert this same div_id variable, no matter which div the handler is actually handling. Div clicks are handled, but when they are handled, each handler says that it's the last div.
Which is no good!
The bottom code alleviates this by bringing the div_id variable inside of make_handler's closure before passing it to the event handler function that is created and returned. This new event handler function reports a div_id variable that is scoped to its progenitor make_handler function. So each event handler function no longer pulls in the same div_id from outside; it instead pulls in the div_id that exists within its parent make_handler function's closure. Since make_handler was called with a different div_id each time in order to create each event handler function, each event handler function now pulls in its own unique div_id, which it will dutifully report when clicked.
So, thanks to judicious use of function closure, each event handler function now reports its own div_id, all of which are different despite having exactly the same variable name.
I hope that does a decent job of explaining it! It was a lot of fun to work through mentally.
I just finished reading and doing all the exercises for A Smarter Way to Learn Javascript, so "document.getElementById()" and "function thisArbitraryFunction() {" are pretty well committed to muscle memory. I know that eyeballs are the only body parts that are supposed to move during REM sleep, but I wouldn't be surprised if my fingers are twitching those commands out during my dreams to come...
Anyway! How about some content?
As part of our "homework" we have been watching Douglas Crockford's "Crockford on Javascript" lecture series on Youtube. The first is a fascinating look through computer and programming language history up until Javascript, the second touches on the particulars and history of Javascript itself, while the third outlines strengths/peculiarities of what Crockford considers Javascript's greatest asset: its functions.
I'd like to consider some code presented toward the end of the lecture, which Crockford presents as a common mistake made by Javascript developers:
Crockford points out that in the top code, all event handlers created by the loop will report the same div_id (the last one) no matter which one is clicked, which is not the desired behavior. In the bottom code, however, each div_id is reported (alerted) correctly because the "make_handler" function is pulled outside of the loop. He tells us that this fixes the problem because of function closure.
Hmm.. I had to pause for a while and give this one some thought. Here's how I see it:
In the top loop, we've created some arbitrary number of event handlers. The loop makes them all at once, and after their respective geneses they all do their thing, handling events as event handlers are wont to do. Each handler is supposed to listen for clicks on a specific div, and alert their specific div when it's clicked.
Great, except that the "div_id = divs[i].id;" line occurs outside of the actual "divs[i].onclick = function () {" functions that are created. In other words, div_id exists outside of the generated functions' closures; like Python (and unlike Ruby unless you explicitly make a global or instance variable, afaik), functions are able to pull variables "above" them in scope in to use, but variables that are declared/reassigned within them are scoped to their respective function closures.
So what happens here is that we get event handler functions that each handle click events for their particular divs. They do this job admirably, but when the actual functions are called, they each alert a "div_id" variable that is pulled in into the function's scope from outside of it; "div_id" does not belong to the function's scope; it belongs to the scope that sits one level above each function.
In other words, each function pulls, from outside of its scope, the same "div_id" variable! And this "div_id" will point to the very last div that the iterator "i" iterates through in the "for" loop, since that's the last value that div_id is set to before the loop ends and we stop reassigning it. The loop runs its course, all the event handlers are created, and div_id winds up set to the very last value of divs[i]. Each individual event handler function now reaches outside of its scope to pull in and alert this same div_id variable, no matter which div the handler is actually handling. Div clicks are handled, but when they are handled, each handler says that it's the last div.
Which is no good!
The bottom code alleviates this by bringing the div_id variable inside of make_handler's closure before passing it to the event handler function that is created and returned. This new event handler function reports a div_id variable that is scoped to its progenitor make_handler function. So each event handler function no longer pulls in the same div_id from outside; it instead pulls in the div_id that exists within its parent make_handler function's closure. Since make_handler was called with a different div_id each time in order to create each event handler function, each event handler function now pulls in its own unique div_id, which it will dutifully report when clicked.
So, thanks to judicious use of function closure, each event handler function now reports its own div_id, all of which are different despite having exactly the same variable name.
I hope that does a decent job of explaining it! It was a lot of fun to work through mentally.
Tuesday, April 7, 2015
.bash_profile? .bashrc?
Day 2 was essentially an all-day installapalooza. It was quite the undertaking for our instructor, who needed to walk 24 adults with different OSs, prior installations/environments, levels of experience with the command line, etc., through the process of getting Node.js, nvm and npm all set up in just one day.
Things went smoothly for me, for the most part, although I encountered some problems in getting nvm to work after running its install script as directed here: https://github.com/creationix/nvm.
Had something to do with path/environment issues, so I inserted the following line into my bash profile (.bashrc) as directed by my instructor (and nvm's github readme): "source ~/.nvm/nvm.sh".
But this didn't fix the problem. I was mystified, at which point my instructor came around and showed me one of the many reasons it's preferable to have an instructor instead of hacking it alone: he figured out in minutes what would've had me spinning my wheels for hours.
I'd been editing my .bashrc file to no avail, after which my instructor had me edit the .bash_profile file. I hadn't known that there were multiple bash profile files, nor did I know why that is the case prior to looking into it a bit more deeply, which led me to this blog post on the subject:
Sunday, April 5, 2015
My move from Japan is complete! This post comes to you from Nashville, Tennessee, where I spent my college days at Vandy and, now, where I'll be taking my next steps toward a career as a developer.
I spent much of February and pretty much all of March figuring out what to do next-- my teaching contract expired on March 31 and I'd already decided long ago (since last October, I believe) that I was going to be making a career change one way or another. So another year as a teacher was already ruled out. In retrospect I'm glad to have placed that pressure upon myself.
I gave consideration to staying at a relative's place in Florida and continuing to self-study Rails, but at some point in the process of furious googling for beginning developer opportunities I found out about Nashville Software School, a 6-month programming web development bootcamp that offers an apprenticeship program for residents/people with ties to Tennessee.
Lucky for me, right? I grew up and went to college in TN. Submitted my documents, interviewed, and now I'm sitting in Nashville (and my apartment is only about a 5-minute walk away from the school) waiting for classes to start tomorrow.
So that's what I've been up to. Came back to the US by way of Mexico City on 3/31.
I've been studying Rails until now, but my schedule from here looks like:
4/2015 - 7/2015: Front-end tech. (HTML/CSS/Javascript/JQuery/AJAX/etc.)
7/2015 - 10/2015: Node.js framework (backend)
So my backend experience is going to move from Rails to Node.js. Which is a bit of a change, but I'm up for anything. I'm super happy and excited to get all of my time and energy focused on programming and making this happen.
To that end I'm also looking to participate in Nashville meetups, principally Javascript from here on out, I suppose. And hackathons. Spent some time this morning getting signed up for those.
Will keep the blog updated!
I spent much of February and pretty much all of March figuring out what to do next-- my teaching contract expired on March 31 and I'd already decided long ago (since last October, I believe) that I was going to be making a career change one way or another. So another year as a teacher was already ruled out. In retrospect I'm glad to have placed that pressure upon myself.
I gave consideration to staying at a relative's place in Florida and continuing to self-study Rails, but at some point in the process of furious googling for beginning developer opportunities I found out about Nashville Software School, a 6-month programming web development bootcamp that offers an apprenticeship program for residents/people with ties to Tennessee.
Lucky for me, right? I grew up and went to college in TN. Submitted my documents, interviewed, and now I'm sitting in Nashville (and my apartment is only about a 5-minute walk away from the school) waiting for classes to start tomorrow.
So that's what I've been up to. Came back to the US by way of Mexico City on 3/31.
I've been studying Rails until now, but my schedule from here looks like:
4/2015 - 7/2015: Front-end tech. (HTML/CSS/Javascript/JQuery/AJAX/etc.)
7/2015 - 10/2015: Node.js framework (backend)
So my backend experience is going to move from Rails to Node.js. Which is a bit of a change, but I'm up for anything. I'm super happy and excited to get all of my time and energy focused on programming and making this happen.
To that end I'm also looking to participate in Nashville meetups, principally Javascript from here on out, I suppose. And hackathons. Spent some time this morning getting signed up for those.
Will keep the blog updated!
Subscribe to:
Posts (Atom)