tag:blogger.com,1999:blog-36361921420406124462024-03-13T17:58:02.206-06:00Triple EqualsBrandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.comBlogger12125tag:blogger.com,1999:blog-3636192142040612446.post-40261247282899928122014-05-15T22:10:00.001-06:002020-11-17T20:04:05.945-07:00The making of my Rummy gameMost good developers have at some time in their life created a game. I decided I wanted to join that group so I set out to make something.<br />
<br />
While a scroller could provide some problems I haven't solved before, or something 3D could give me an opportunity to use WebGL, I ultimately landed on a simple <a href="https://iambrandonn.github.io/rummy/" target="_blank">rummy card game</a>. <br />
<br />
My first draft used Canvas with <a href="http://www.greensock.com/gsap-js/" target="_blank">GSAP</a>, which worked well. However I eventually found it is hard to determine what elements were clicked on when everything is drawn to canvases. So... I reverted back to plain HTML and CSS transitions/transforms. <br />
<br />
I also took the opportunity to write it with purely functional vanilla JavaScript. In the past with anything of much complexity I always fell back to my OOP roots, but this worked well.<br />
<br />
Something unique to this game is that the entire state is always saved in localStorage so anytime you navigate away from the page, you can navigate back and everything will be exactly as it was left.<br />
<br />
So, here is my <a href="https://iambrandonn.github.io/rummy/" target="_blank">rummy game</a> ( <a href="http://www.cecese.com/rummy/">https://iambrandonn.github.io/rummy/</a> ).<br />
<br />Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com12tag:blogger.com,1999:blog-3636192142040612446.post-49029420978250231262013-02-18T18:08:00.003-07:002014-05-09T09:24:17.402-06:00The new Web Speech API => a Flash Cards Application!<div>
In the last couple of months I've been helping my daughter memorize her multiplication and division tables. To help her get faster we've used traditional flash cards, which work pretty well. One day I thought to myself "a computer could easily listen to a student's voice and show appropriate cards... it could even keep score." I looked around to see if there were any JavaScript libraries that worked with the microphone to provide speech recognition, but didn't find anything worthwhile. The best I could get was to use Emscripten to port a C library. I put it on the back burner and worked on some other things for awhile. </div>
<div>
<br /></div>
<div>
Then I saw a post about Google Chrome version 25. In it is implemented the new Web Speech API. HTML5Rocks did an article covering some of the capabilities <a href="http://updates.html5rocks.com/2013/01/Voice-Driven-Web-Apps-Introduction-to-the-Web-Speech-API" target="_blank">here</a>. In short, the API allows you to add speech recognition to your apps! Just what I needed!</div>
<div>
<br /></div>
<div>
So off to work on the <a href="https://iambrandonn.github.io/FlashCards/">app</a>... The API is pretty simple. These are the steps to use it:</div>
<div>
<ol>
<li>You create an instance of the object, via <span style="font-family: Courier New, Courier, monospace;">new webkitSpeechRecognition()</span></li>
<li>Set <span style="font-family: Courier New, Courier, monospace;">continuous </span>to true or false to specify whether it should stop after giving a result or keep listening continuously.</li>
<li>Set <span style="font-family: Courier New, Courier, monospace;">interminResults </span>to true or false to specify if you want only the final result or all results.</li>
<li>Provide callbacks via <span style="font-family: Courier New, Courier, monospace;">onstart, onresult, onerror, and onend</span>.</li>
</ol>
<div>
I hooked it all up and built the application around it. I think it turned out pretty well. I use localStorage to track high scores and store custom lists.</div>
</div>
<div>
<br /></div>
<div>
For the main page I went Vanilla JS (well almost... I used the Handlebars VM for templates). So the page has a pretty light footprint (35k). And 15k of that is Google Analytics, so the actual application code (including the Handlebars VM) is only 20k. My experience is that Vanilla JS is a little harder than typical jQuery, Backbone, etc... but it is definitely light and fast. </div>
<div>
<br /></div>
<div>
Anyway... here's the link to the app: <a href="https://iambrandonn.github.io/FlashCards/">https://iambrandonn.github.io/FlashCards/</a></div>
<div>
<br /></div>
<div>
Have fun!</div>
<div>
<br /></div>
Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com6tag:blogger.com,1999:blog-3636192142040612446.post-67491133050184727862012-10-20T10:46:00.000-06:002012-10-20T10:46:26.298-06:00Keeping Your Knowledge CurrentLately I've been part of several discussions about keeping our tech skills up to date. This post discusses my techniques for staying current.<br />
<ul>
<li>Commit to spending time EVERY workday (and often non-workdays) keeping up with things. Everyone feels pressure to complete current projects on time... but we can't let that get in the way of maintaining our competency. I personally spend one to two hours every day scanning various communities and investigating new things. As a worker in the tech industry you can coast for awhile on your current knowledge, but soon you'll be wasting your time and the resources of your employer using old methods and technologies.</li>
</ul>
<ul>
<li>There are new libraries and technologies released daily. Here is how I evaluate whether one is worth my time or not.</li>
<ul>
<li>The easiest way is to watch how frequently it is mentioned. If it's mentioned only once and not heard about again... don't waste your time. If you hear about it over and over from multiple sources, especially over an extended period of time, you better check it out.</li>
<li>If you decide to investigate it, search for the "main" page about it. Usually this is the product or project home page. That should give you a quick idea of what it is about. In your mind compare it to other similar products. If it looks like something that may take off, read through the sites tutorials if they exist. Also check for other blogs/sites with tutorials or discussions on it. I usually put a product into one of three categories at this point.</li>
</ul>
</ul>
<ol><ul>
<ul>
<li>This is cool! - <i>I need to try out some actual code in the next couple days.</i></li>
<li>Interesting - <i>Ok... I learned what it is. I have that frame of reference. Now I will wait to see if it catches on or not. If so, I'll invest more time at that point. </i> </li>
<li>Redundant or not useful - <i>Don't waste any more time on it.</i></li>
</ul>
</ul>
</ol>
<ul>
<li>I encourage you to find your own sources of the latest news and trends. I have three main sources:</li>
</ul>
<ol>
<ul>
<li><a href="http://news.ycombinator.com/" target="_blank">Hacker News</a> - I subscribe to their RSS feed so I see every post, but if you are short on time just check their home page a couple times a day. The most useful articles will float to the top. Some people instead prefer <a href="http://www.reddit.com/" target="_blank">reddit</a>. </li>
<li><a href="http://twitter.com/" target="_blank">Twitter</a> - I was a latecomer to Twitter. I still don't tweet much, but I have found it invaluable as a tool to follow some of the influential people in the industry. (FYI... if someone consistently tweets irrelevant things that pollute my stream, they're gone. Even if they occasionally post something great, I can't waste my time reading what they had for breakfast.) <a href="http://twitter.com/NichollsBrandon/following" target="_blank">This</a> is who I follow. I particularly recommend:</li>
</ul>
<ol><ul>
<li><a href="http://twitter.com/paul_irish" target="_blank">Paul Irish</a> - One of the more influential developer evangelists at Google</li>
<li><a href="http://twitter.com/BrendanEich" target="_blank">Brendan Eich</a> - Creator of JavaScript and Mozilla CTO</li>
<li><a href="http://twitter.com/dalmaer" target="_blank">Dion Almer</a> and <a href="http://twitter.com/bgalbs" target="_blank">Ben Galbraith</a> - Top web dudes at Walmart (currently)</li>
<li><a href="http://twitter.com/igrigorik" target="_blank">Ilya Grigorik</a> - Another developer advocate at Google</li>
<li><a href="http://twitter.com/tvalletta" target="_blank">Tom Valetta</a> - Open web evangelist</li>
<li><a href="http://twitter.com/souders" target="_blank">Steve Souders</a> - One of the top web performance engineers</li>
</ul>
</ol>
<ul>
<li>RSS feeds - I use <a href="http://google.com/reader/" target="_blank">Google Reader</a>. Here are the tech <a href="http://www.google.com/reader/bundle/user%2F15968624918290097673%2Fbundle%2FTech%20feeds" target="_blank">feeds</a> I follow (probably too much for some).</li>
</ul>
</ol>
Some people go to tech conferences as a way to stay current. In my thinking you are WAY too slow if you are doing most of your learning at conferences. That means someone else already investigated it, learned about it, prepared/submitted a talk on it, got accepted, and is now giving a talk on it. That's often a six month or more lag. Ouch.<br />
<br />
Employees in our industry are in high demand and we are usually paid well and have employment opportunities across the country. Staying current is a small investment that justifies that luxury. <br />
<br />
What are your tips for staying current?Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com2tag:blogger.com,1999:blog-3636192142040612446.post-60634858793970712392012-10-01T20:59:00.006-06:002020-11-17T20:24:04.401-07:00Color CamLast week I had another idea for a crazy webcam oriented experiment. I imagined a site that played music and showed the video from the webcam. A technique to determine movement would be used, similar to what <a href="http://iambrandonn.github.io/WebcamSwiper" target="_blank"><span style="color: #9fc5e8;">WebcamSwiper</span></a> does. The movement would be shown as random colors splashes with the intensity/brightness varying based on the volume of the music. It seemed like it would be kinda psychedelic, but cool. <br />
Well, I finished it. <a href="https://iambrandonn.github.com/ColorCam" target="_blank"><span style="color: #9fc5e8;">Here</span></a>. It's not bad... but didn't turn out as cool as I thought. Oh well, moving on.<br />
<br />Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com0tag:blogger.com,1999:blog-3636192142040612446.post-58422693999093668562012-09-24T22:35:00.000-06:002013-04-05T22:28:54.360-06:00Webcam Swiper<br />
I've spent a little time lately working on an experiment that uses the new <span style="font-family: Courier New, Courier, monospace;">getUserMedia()</span> method. I'm calling it the <a href="http://iambrandonn.github.io/WebcamSwiper" target="_blank"><span style="color: #9fc5e8;">Webcam Swiper</span></a>. Chrome and Firefox now support Webcam access, although Firefox < 20 requires turning on a flag in about:config.<br />
<br />
It's a page that displays a book. If you allow webcam access it will watch for you swiping your hand left or right through the air, which triggers a page turn in the appropriate direction. <br />
<br />
I was inspired to try this when I saw the cool <a href="http://www.soundstep.com/blog/experiments/jsdetection/" target="_blank"><span style="color: #9fc5e8;">Magic Xylophone</span></a>. I thought of all the cases where someone might want to make a simple directional gesture and have something happen on the page. Image Carousels could rotate, the next item in a list could be displayed, book pages could be turned, etc...<br />
<br />
To implement this I had to figure out how to detect when a hand had moved from one side of the screen to the other. I started by detecting motion the same way that the Magic Xylophone does. First turn the image from the webcam to greyscale so I only have to worry about brightness and not color changes. Then, comparing one frame to the next, watch for any pixels that change intensity more than some given threshold. Next I determine what I call the "motion weight" for the given frame. Basically any pixel on the left side of the screen which is considered to have movement, subtracts from the weight. Any pixel on the right side of the screen which has movement adds to the weight. Total them all up and we get a number that summarizes where the most movement is occurring on the screen. Now all we need to do is compare the "motion weight" over the last series of frames. If we have a highly negative weight which then quickly shifts to a highly positive weight, we know the user just swiped right. If it is positive and goes negative, the user just swiped left. A custom event is fired on the body element of the page. Then whoever is listening for the event can do whatever they want. In my case I do a couple CSS transitions and transforms to turn the page of the book. <br />
<br />
That's all there is to it. I had some problems with varying light level, so I sample every 50 frames and calibrate the sensitivity based on the ambient light level in the room. Also I adjust for slower hardware by timing each frame analysis. If it is taking too long I lower the scan frequency. Otherwise it stays high. <br />
<br />
I've made this all into a <a href="https://github.com/iambrandonn/WebcamSwiper" target="_blank"><span style="color: #9fc5e8;">library</span></a> which should be fairly easy to use. <br />
<br />
Include the webcam-swiper-0.1.js with a script tag or the loader of your choice. <br />
<br />
Then bind the swipe events however you choose. Example with jQuery:<br />
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> $("body").bind("webcamSwipeLeft", yourLeftEventHandler);</span><br />
<span style="font-family: Courier New, Courier, monospace;"> $("body").bind("webcamSwipeRight", yourRightEventHandler);</span><br />
<div>
<br /></div>
<div>
Start the webcam access with a call to the global initializeWebcamSwiper function like this:</div>
<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> window.initializeWebcamSwiper();</span><br />
<br />
Now it is running! If you choose to stop it call<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> window.destroyWebcamSwiper();</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: inherit;">Play with it and feel free to improve it or give any feedback.</span>Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com28tag:blogger.com,1999:blog-3636192142040612446.post-51624403894063365692011-11-24T21:54:00.001-07:002011-11-25T09:38:19.501-07:00Local Variables and Variable Hoisting<span class="Apple-style-span" style="font-family: inherit;">The other day I ran across a few interesting features of JavaScript variable scopes. Consider this code:</span><br />
<span class="Apple-style-span" style="color: red;"><br /></span><br />
<span class="Apple-style-span" style="color: red; font-family: 'Courier New', Courier, monospace;"><span class="js-keyword" style="font-size: 12px; line-height: 15px;">function </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">doSomething</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">) </span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">{</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-keyword" style="font-size: 12px; line-height: 15px;">var </span><span class="js-variabledef" style="font-size: 12px; line-height: 15px;">a </span><span class="js-operator" style="font-size: 12px; line-height: 15px;">= </span><span class="js-atom" style="font-size: 12px; line-height: 15px;">1</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-keyword" style="font-size: 12px; line-height: 15px;">if </span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-atom" style="font-size: 12px; line-height: 15px;">true</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">) </span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">{</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-keyword" style="font-size: 12px; line-height: 15px;">var </span><span class="js-variabledef" style="font-size: 12px; line-height: 15px;">a </span><span class="js-operator" style="font-size: 12px; line-height: 15px;">= </span><span class="js-atom" style="font-size: 12px; line-height: 15px;">2</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">alert</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-localvariable" style="font-size: 12px; line-height: 15px;">a</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">}</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">alert</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-localvariable" style="font-size: 12px; line-height: 15px;">a</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">}</span><br style="font-size: 12px; line-height: 15px;" /><br style="font-size: 12px; line-height: 15px;" /><span class="js-variable" style="font-size: 12px; line-height: 15px;">doSomething</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span></span><br />
<span class="js-punctuation" style="font-family: Inconsolata, Monaco, Consolas, 'Andale Mono', 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace; font-size: 12px; line-height: 15px;"><br /></span><br />
<span class="js-punctuation" style="line-height: 15px;"><span class="Apple-style-span" style="font-family: inherit;">What would you expect? If you are used to coding in a C like language, you would expect the first alert to be 2 and the second to be 1. In JavaScript however this is not the result. We get 2 for both alerts. How come?</span></span><br />
<span class="js-punctuation" style="line-height: 15px;"><span class="Apple-style-span" style="font-family: inherit;"><br /></span></span><br />
<span class="js-punctuation" style="line-height: 15px;"><span class="Apple-style-span" style="font-family: inherit;">It turns out that JavaScript has no concept of "block-level" scoping (specific to the if block in this example). Variables are either globally scoped or they are function scoped. That means that even though we are in an if-block, we are still using the same scope as we were before entering the block. So in our example the variable "a" is re-declared and assigned to 2, and it continues to be in scope after leaving the function, and will still be available until the <i>function</i> ends.</span></span><br />
<span class="js-punctuation" style="line-height: 15px;"><span class="Apple-style-span" style="font-family: inherit;"><br /></span></span><br />
<span class="js-punctuation" style="line-height: 15px;"><span class="Apple-style-span" style="font-family: inherit;">Here is <a href="http://jsfiddle.net/XQRG3/" target="_blank">a jsFiddle</a> if you would like to play with it.</span></span><br />
<span class="js-punctuation" style="line-height: 15px;"><span class="Apple-style-span" style="font-family: inherit;"><br /></span></span><br />
<span class="Apple-style-span" style="line-height: 15px;">Reading about this led me to another interesting topic concerning variable scopes. Look at this code:</span><br />
<span class="Apple-style-span" style="color: red; line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="color: red; font-family: 'Courier New', Courier, monospace;"><span class="js-variable" style="font-size: 12px; line-height: 15px;">a </span><span class="js-operator" style="font-size: 12px; line-height: 15px;">= </span><span class="js-atom" style="font-size: 12px; line-height: 15px;">1</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="js-keyword" style="font-size: 12px; line-height: 15px;">function </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">doSomething</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">) </span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">{</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">alert</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-localvariable" style="font-size: 12px; line-height: 15px;">a</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-keyword" style="font-size: 12px; line-height: 15px;">var </span><span class="js-variabledef" style="font-size: 12px; line-height: 15px;">a </span><span class="js-operator" style="font-size: 12px; line-height: 15px;">= </span><span class="js-atom" style="font-size: 12px; line-height: 15px;">2</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">alert</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-localvariable" style="font-size: 12px; line-height: 15px;">a</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">}</span><br style="font-size: 12px; line-height: 15px;" /><br style="font-size: 12px; line-height: 15px;" /><span class="js-variable" style="font-size: 12px; line-height: 15px;">doSomething</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span></span><br />
<span class="Apple-style-span" style="line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="line-height: 15px;">To start we have a global variable named a which is assigned the value of 1. Then when doSomething is called the alert displays the global variables value, a function level variable is created and assigned 2, which is then alerted. Right? Nope...</span><br />
<span class="Apple-style-span" style="line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="line-height: 15px;">The first alert displays "undefined" while the second is 2. Why doesn't the first fall back to the global variable? This is due to the way JavaScript handles declarations. They are automatically "hoisted" to the top of the function, leaving code that looks would look like this:</span><br />
<span class="Apple-style-span" style="color: red; line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="color: red;"><span class="js-variable" style="font-family: 'Courier New', Courier, monospace; font-size: 12px; line-height: 15px;">a </span><span class="js-operator" style="font-family: 'Courier New', Courier, monospace; font-size: 12px; line-height: 15px;">= </span><span class="js-atom" style="font-family: 'Courier New', Courier, monospace; font-size: 12px; line-height: 15px;">1</span><span class="js-punctuation" style="font-family: 'Courier New', Courier, monospace; font-size: 12px; line-height: 15px;">;</span></span><br />
<span class="Apple-style-span" style="color: red; font-family: 'Courier New', Courier, monospace;"><span class="js-keyword" style="font-size: 12px; line-height: 15px;">function </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">doSomething</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">) </span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">{</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> var a;</span></span><br />
<span class="Apple-style-span" style="color: red; font-family: 'Courier New', Courier, monospace;"><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">alert</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-localvariable" style="font-size: 12px; line-height: 15px;">a</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-variabledef" style="font-size: 12px; line-height: 15px;">a </span><span class="js-operator" style="font-size: 12px; line-height: 15px;">= </span><span class="js-atom" style="font-size: 12px; line-height: 15px;">2</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="whitespace" style="font-size: 12px; line-height: 15px;"> </span><span class="js-variable" style="font-size: 12px; line-height: 15px;">alert</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-localvariable" style="font-size: 12px; line-height: 15px;">a</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span><br style="font-size: 12px; line-height: 15px;" /><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">}</span><br style="font-size: 12px; line-height: 15px;" /><br style="font-size: 12px; line-height: 15px;" /><span class="js-variable" style="font-size: 12px; line-height: 15px;">doSomething</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">(</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">)</span><span class="js-punctuation" style="font-size: 12px; line-height: 15px;">;</span></span><br />
<div>
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-style-span" style="color: red; font-size: 12px; line-height: 15px;"><br /></span></span></div>
<span class="Apple-style-span" style="line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="line-height: 15px;">Now it makes sense why we would get an "undefined". The function scoped variable is completely hiding the global one, and it hasn't been assigned yet. This is an important point... declarations are hoisted but assignments are not. </span><br />
<span class="Apple-style-span" style="line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="line-height: 15px;">Again, here is <a href="http://jsfiddle.net/h2KLC/" target="_blank">a jsFiddle</a> with the scenario. </span><br />
<span class="Apple-style-span" style="line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="line-height: 15px;">Ben Cherry also has a good <a href="http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting" target="_blank">blog post</a> about this issue. </span><br />
<span class="Apple-style-span" style="line-height: 15px;"><br /></span><br />
<span class="Apple-style-span" style="line-height: 15px;"><br /></span><br />
<br />
<span class="Apple-style-span" style="line-height: 15px;"><br /></span>Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com0tag:blogger.com,1999:blog-3636192142040612446.post-29782650695955320602011-11-02T22:29:00.000-06:002011-11-02T22:29:27.567-06:00The debugger statementThe debugger statement in JavaScript will cause a debugger (like FireBug or the Chrome developer tools) to pause execution just as if there was a breakpoint at that line. This is most useful when you have dynamically generated code or whenever you don't have a chance to set a breakpoint on a line before the code executes. <div><br />
</div><div>Simple example:</div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">var a = 44;</span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">debugger;</span></div><div><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">alert(a);</span></div><div><br />
</div><div>In this case the debugger (if open) will pause before the alert is shown. </div><div><br />
</div><div>Here are the <a href="https://developer.mozilla.org/en/JavaScript/Reference/Statements/debugger">MDN docs</a> for the debugger statement.</div><div><br />
</div>Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com1tag:blogger.com,1999:blog-3636192142040612446.post-12784763247867447162011-08-23T23:26:00.000-06:002011-08-23T23:26:32.764-06:00JavaScript Strict Mode<br />
<div class="MsoNormal"><span class="Apple-style-span" style="line-height: 18px;"></span></div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;">Many of us have been taught that global variables are evil. They contribute to code which is difficult to maintain. The JavaScript language, however, allows global variables and they are quite common. Luckily JavaScript has a lesser known mode called “strict mode” which will throw an error if we try to create a global variable.</div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;"><br />
</div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;">To use strict mode you begin your script files with </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">“use strict”;</span><span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif;"> The quotes are needed also. This will make all code inside this JavaScript file run under strict mode. Any functions called from within this file will also run in strict mode. <a href="http://jsfiddle.net/WVYTP/">Here</a> is a quick example of code that allows global variables because it is not in strict mode. And <a href="http://jsfiddle.net/4GhbT/">here</a> is the same code which throws an error when trying to create a global variable. </span></div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;"><br />
</div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;">Strict mode tightens down a few other language features, most of which you won’t/shouldn’t care about anyway. For instance normally you can have a function with this signature:</div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> function sum(x, x){};</span></div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;"><br />
</div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;">Why you would want two parameters to have the same name, or how you would expect the code to work… I don’t know. But strict mode throws an error if you try. I consider that a good thing. </div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;"><br />
</div><div class="MsoNormal" style="font-family: Arial, Helvetica, sans-serif;">For more info check out the <a href="https://developer.mozilla.org/en/JavaScript/Strict_mode">MDN page about strict mode</a>.</div><br />
Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com2tag:blogger.com,1999:blog-3636192142040612446.post-19071450870508895732011-07-29T23:48:00.000-06:002011-07-29T23:48:57.877-06:00All about function argumentsJavaScript allows a variable number of arguments to be passed into a function. Thats actually a pretty cool feature that some languages (Java) have only added in the last few versions. Lets look at it a little more by examining a function that takes two numbers and returns the sum:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span></span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">function sum(firstNum, secondNum) {</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return firstNum + secondNum;</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<br />
We can call this function like this:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>// Will return 14</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum(3, 11); </span><br />
<span class="Apple-tab-span" style="white-space: pre;"> </span><br />
But we are allowed to pass as many arguments to the function as we want:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>// Will still return 14</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum(3, 11, 4, 99, 0, 2);</span><br />
<br />
No errors are thrown, however the function only adds the first two numbers, as we coded it to do. How can we take advantage of a variable number of arguments? This is where the <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">arguments</span> object comes in. It is available to you any time you are executing code within a function. Its an array like object that contains each of the arguments that were passed to the current function. Not just the declared parameters... but everything that was actually passed at call time. <br />
<br />
Lets see how we can make our sum function work better using the <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">arguments</span> object:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>function sum() {</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>var runningTotal = 0;</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>for (var i = 0; i < arguments.length; i++) {</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>runningTotal += arguments[i];</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>return runningTotal;</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>}</span><br />
<br />
We now loop through each of the arguments adding them in turn. <br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>// Will return 14</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum(3, 11);</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>// Will return 119</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>sum(3, 11, 4, 99, 0, 2);</span><br />
<br />
So now that we can determine our arguments at call time, is there an easy way to find out (with code) how many declared parameters a function is expecting? Yup. Simply check the <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">length</span> property of the function. Example:<br />
<br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>function takesThree(x, y, z) {}</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>console.log(takesThree.length);</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>--> 3</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>function takesOne(first){}</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>console.log(takesOne.length);</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>--> 1</span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span></span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>function takesNone(){}</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>console.log(takesNone.length);</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>--> 0</span><br />
<span class="Apple-tab-span" style="white-space: pre;"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span></span><br />
<div><br />
</div>Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com0tag:blogger.com,1999:blog-3636192142040612446.post-24779174800086909482011-07-22T22:34:00.000-06:002011-07-22T22:34:38.233-06:00When do I use the === operator in JavaScript?<div class="MsoNormal">As new JavaScript programmers spend time with the language they often run into an operator they are unfamiliar with.<span style="mso-spacerun: yes;"> </span>Most of us are familiar with the double equals (==) operator.<span style="mso-spacerun: yes;"> </span>But what does the triple equals (===) operator, aka strict equals operator, do?<span style="mso-spacerun: yes;"> </span>Why would we use it over ==?</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">Let me begin by explaining how the == operator works and then contrast the === operator.<span style="mso-spacerun: yes;"> </span>Suppose I have the following code:</div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">var aNum = 3;<o:p></o:p></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">var aStr = “3”;<o:p></o:p></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">console.log(aNum == aStr);<o:p></o:p></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">// output is true<o:p></o:p></span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal">Even though aNum is a number and aStr is a string… the variables are considered equal by the == operator.<span style="mso-spacerun: yes;"> </span>This is because == will attempt to convert the variables to the same type before comparing them.<span style="mso-spacerun: yes;"> </span>As long as you are aware that happens, it is usually OK, and sometimes helpful.<span style="mso-spacerun: yes;"> </span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal">Now let’s look at the same code with the === operator:</div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">var aNum = 3;<o:p></o:p></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">var aStr = “3”;<o:p></o:p></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">console.log(aNum === aStr);<o:p></o:p></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New'; font-size: 13px; line-height: 14px;"> </span><span style="font-family: "Courier New"; font-size: 10.0pt; line-height: 115%;">// output is false<o:p></o:p></span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal">The === operator makes no attempt to convert the variables before comparing, so of course the variables are not equal.<span style="mso-spacerun: yes;"> </span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal">To summarize, any time you are doing an equality comparison when variable type does matter, use the === operator.<span style="mso-spacerun: yes;"> </span>If you don’t care what the variable’s type is, or specifically want type coercion, use the == operator.<span style="mso-spacerun: yes;"> </span></div>Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com0tag:blogger.com,1999:blog-3636192142040612446.post-19166588838439257392011-07-16T17:28:00.002-06:002011-07-16T17:31:56.749-06:00How do I convert a String to a Number in JavaScript?<div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">Variables in JavaScript are not strongly typed. So if I have a variable named x:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">var x;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">I can assign anything I want to it:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">X = 4; // legal</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> X = “a string”; // also legal</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> X = {width: 45, height: 30}; // still legal</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">This can be nice at times… but if we aren't careful it can also introduce bugs. For instance:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var width = “3”;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> width += 7;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // width now equals “37”, not 10</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">Cases like this require us to first convert the string to a number. There are three methods of doing this which I will discuss:</span></div><br />
<div class="MsoNormal"></div><ul><li>The unary + operator</li>
<li>The global function parseInt()</li>
<li>The global function parseFloat()</li>
</ul><br />
<div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">If you know the string you are converting only represents a number (e.g. “3” or “5.9”, not “34px”) you can use the unary + operator. Simply place a “+” right before string, and you now have a number. Example:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">var width = “3”;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">var height = 9;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">var area = height * (+width);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">// area now equals 27</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">Note that you are not adding anything to the variable (that would be a binary operator), you are simply making it a number. Again, this only works with a string that represents a number. The following will give </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">NaN</span><span class="Apple-style-span" style="font-family: inherit;"> (not a number):</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">var width = +“5px”;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // width now equals NaN</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">So, what to do with “5px”? Do we have to remove the non-numeric characters first? Nope. The parseInt function helps us out here. It will return an integer based on the first number it finds. So the previous failure would now look like this:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var width = parseInt(“5px”);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // width now equals 5</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">The non-numeric characters <i style="mso-bidi-font-style: normal;">after</i> the number are ignored. Note that non-numeric characters found <i style="mso-bidi-font-style: normal;">before</i> the number will cause a </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">NaN</span><span class="Apple-style-span" style="font-family: inherit;"> to be returned. Example:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var width = parseInt(“w 5px”);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // width now equals NaN</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">FYI, you can also pass a second parameter to the function which is the radix of the first argument. </span><span class="Apple-style-span" style="font-family: inherit;">Example:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">var x = parseInt("10010", 2);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">// x now equals 18</span></div><div class="MsoNormal" style="text-indent: .5in;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">This works great, but what if we want a floating point number? The global function parseFloat will do very similar work, returning a floating point number instead. Example:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var pi = parseFloat(“3.14”);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // pi now equals 3.14</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">The same rules apply about having characters before and after as do to the parseInt function. </span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var pi = parseFloat(“3.14 degrees”);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // pi now equals 3.14</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var pi = parseFloat(“x 3.14 degrees”);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // pi now equals NaN</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">The parseFloat function can also take a string in scientific notation:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var x = parseFloat("3.14e5");</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> x now equals 314000</span></div><div class="MsoNormal" style="text-indent: .5in;"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">Finally a quick way of converting back to a String is as follows:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var score = String(3722);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // score now is a string of “3722”</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var label = “Your high score is “ + score;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">As this demonstrates, conversion to a String is not needed as frequently because any time we add a string to a number… we get a string concatenation not a numeric addition. </span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">Bonus material:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">There are two more global functions which may be helpful in some cases:</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> isNaN() </span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> isFinite()</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: inherit;">isNaN() will return true if the variable currently is NaN (not a number). isFinite() will return false if the argument passed in is positive infinity, negative infinity, or NaN. </span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">// will return true (because x is 3)</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> isFinite(3 / 1); </span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">// will return false (because x is positive infinity)</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">isFinite(3 / 0); </span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">// will return false</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">isNaN(4); </span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">// will still return false because</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> //</span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> “4” can easily be converted to a number</span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">isNaN(“4”); </span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">// will return true because the string can’t </span><br />
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">be easily converted to a number.</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">isNaN(“4px”); </span></div><div class="MsoNormal"><br />
</div>Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com0tag:blogger.com,1999:blog-3636192142040612446.post-89942974526866941512011-07-09T13:48:00.000-06:002011-07-09T13:48:53.276-06:00How do you make an object final in JavaScript?<div class="MsoNormal">In Java, adding the <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">final</span> modifier to a class prevents the class from being extended.<span style="mso-spacerun: yes;"> </span>C# has a similar keyword in <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">sealed</span>.<span style="mso-spacerun: yes;"> </span>JavaScript, however, does not have a direct equivalent of this functionality... but its latest version does have some related capabilities.<span style="mso-spacerun: yes;"> </span></div><div class="MsoNormal"><span style="mso-spacerun: yes;"><br />
</span></div><div class="MsoNormal">There are three functions which provide varying levels of control:<span style="mso-spacerun: yes;"> </span></div><div class="MsoNormal" style="text-indent: .5in;"></div><ul><li><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Object.freeze(obj)</span></li>
<li><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Object.seal(obj)</span></li>
<li><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Object.preventExtensions(obj)</span></li>
</ul><br />
<div class="MsoNormal">Passing an object into <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Object.freeze()</span> will keep any new properties (or “methods”, which really are properties) from being added, no existing properties can be deleted, and the values of existing properties can’t be changed.<span style="mso-spacerun: yes;"> </span></div><div class="MsoNormal"><span style="mso-spacerun: yes;"><br />
</span></div><div class="MsoNormal">Example:</div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var x = {height:3, width: 4};</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> Object.freeze(x);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> x.color = “red”;<span style="mso-tab-count: 1;"> </span>// may throw a TypeError exception</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> delete(x.width);<span style="mso-spacerun: yes;"> </span>// may throw a TypeError or return false</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> x.height = 7;<span style="mso-spacerun: yes;"> </span>// may throw a TypeError exception</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // x is still {height:3, width:4}</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Object.seal()</span> is similar in that no new properties can be added to the object, no existing properties can be deleted… but the values of existing data properties CAN be changed.<span style="mso-spacerun: yes;"> </span></div><div class="MsoNormal"><span style="mso-spacerun: yes;"><br />
</span></div><div class="MsoNormal">Example:</div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var x = {height:3, width: 4};</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> Object.seal(x);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> x.color = “red”;<span style="mso-spacerun: yes;"> </span>// may throw a TypeError exception</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> delete(x.width);<span style="mso-spacerun: yes;"> </span>// may throw a TypeError or return false</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> x.height = 7;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // x now is {height:7, width:4}</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">Finally the least restrictive function is <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">Object.preventExtensions()</span>.<span style="mso-spacerun: yes;"> </span>It will prevent any new properties from being added, but existing properties can be deleted or modified as normal.<span style="mso-spacerun: yes;"> </span></div><div class="MsoNormal"><span style="mso-spacerun: yes;"><br />
</span></div><div class="MsoNormal">Example:</div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> var x = {height:3, width: 4};</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> Object.preventExtensions(x);</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> x.color = “red”;<span style="mso-spacerun: yes;"> </span>// may throw a TypeError exception</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> delete(x.width);<span style="mso-spacerun: yes;"> </span></span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> x.height = 7;</span></div><div class="MsoNormal"><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"> // x now is {height:7}</span></div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><br />
</div><div class="MsoNormal"><br />
</div><div class="MsoNormal">These functions are new to the latest version of JavaScript, so they are only available in Firefox 4+, Chrome 6+, and IE 9+.<span style="mso-spacerun: yes;"> </span>As of Safari 5 and Opera 11.5, the functions are not yet supported.<span style="mso-spacerun: yes;"> </span></div>Brandonhttp://www.blogger.com/profile/08527759716045284865noreply@blogger.com4