Javascript – Undefined array values vs Undefined array indices

Javascript arrays, like any non-primitive, are technically considered objects. This means various object methods and operators are available to them, but internally they’re a different beast. And this can cause unexpected results when treating them like an object.

This is a simple test you can run in your developer console for your browser.

a = [1, 2, 3]
delete a[2]

If javascript arrays act in a similar fashion to a javascript object, you would expect the array to have shrunk by one element.

It doesn’t.

a.length
-> 3

Well, this is strange, and it gets stranger when you print out the array:

a
-> [1, 2, undefined x 1]

Undefined x 1… What does that mean? Every time you delete an array element, it creates an undefined index.

Now, the mystery thickens when you try and play with undefined values.

a.push(undefined)
-> [1, 2, undefined x 1, undefined]

Wait! Why is there undefined x 1, and a separate, different undefined? How are they different? According to the javascript type system, they are the same:

typeof a[2]
-> "undefined"
typeof a[3]
-> "undefined"
typeof a[2] === typeof a[3]
-> true
a[2] === a[3]
-> true
a[2] == a[3]
-> true

A cursory look suggests they’re entirely equivalent, just represented differently. Unfortunately not.

for (property in a) {
    console.log(property + ' ' + a);
}
-> 0 1
-> 1 2
-> 3 undefined

The index itself can be undefined, or the value can be undefined. In our example, a[2] is an undefined index. The index does not exist. Whereas a[3], the index exists, but its value is undefined. This is made apparent when we enumerated over the indices of our array. Ironically, both of them contribute to the overall length of the array, but only one of them holds a value.

If you’re still having trouble conceptualizing this, think of it as such:

a
-> 0 = 1
-> 1 = 2
-> 2 = ???
-> 3 = undefined

a[2] just doesn’t exist. a[3] does, and it is undefined. Careful, the type of a[2] and a[3] are both undefined, which makes some strange literal sort of sense. Now, I could lecture on the importance of understanding the javascript type system until you, my faithful pupils, flee from my blog. But instead, I’ll leave you with this, the simply way of deleting array elements:

a.length = 2
a
-> [1, 2]
Advertisements

The “No jQuery Challenge”

This post is about Angular.js

I discovered Angular no more than two months ago. The simplicity of it convinced me to start the project that had been brewing in my mind a couple years. When I first stumbled upon Angular, I thought to myself, “Wow, I can make complex web applications really quickly if I combine this with jQuery”.

But funny enough, I discovered as I wrote my application that not only did I not need to use jQuery, I did not even want to. Angular provides an alternative way of thinking about the problems jQuery solves.

It became a point of pride to eschew jQuery. I do have my reasons, however, and I’ll share why the No jQuery Challenge is a great learning tool.

Say you find a jsFiddle example with some HTML:

<div id="container">
  <div id="form">
    <input id="submit" type="submit" value='click'></input>
  </div>
  <!-- more html here --> 
</div>

The resulting webpage looks fairly sparse.

Screen shot 2013-12-18 at 1.32.32 AM

There seems to be something misplaced, but we’re in a hurry so we do what we’re told not to and click the button. When we do, we are greeted by a popup box.

Screen shot 2013-12-17 at 7.29.02 PM

A quick glance at the HTML reveals no understanding as to why the popup box appears, so you check the javascript file.

You’re thinking this is jQuery magic. I’ll just ctrl+f for a $(‘#submit’) and find the javascript that generates the dialog box. Doing so finds us:

$('#submit').attr('value', 'don\'t click');

This explains one mystery, but not the one we’re interested in. Now, the javascript file could be fairly large, so the code we’re looking for might be buried deeper. When ctrl+g finds no other instances of $(‘#submit’), we look back at the HTML to see what other jQuery selectors might be in play.

Maybe the <div id=”form”> is responsible. When we search for the $(‘#form”), we find nothing. Surely, it can’t be the <div id=”container”> responsible for this? So we check, and find this:

$("#container").children().addClass('clickable')

Okay, a class titled ‘clickable’, which seems to be what we’re looking for. When we search for a selector of ‘clickable’, we find what we’ve long been searching for:

$(".clickable > input").bind("click", function () {
  alert("popup");
});

Our quest comes to an end; all inputs whose parents are of ‘clickable’ class gives us a dialog box.

While this example is somewhat farfetched and unnecessarily complex, these sorts of design patterns are pretty much everywhere in large dynamic web apps. The more jQuery is used to manipulate the DOM and alter the project structure, it becomes exponentially more difficult to follow the train of logic.

With that in mind, lets take a look at an Angular implementation of the same functionality:

<div>
  <div ng-click="popup()">
    <input value="{{inputText}}"></input>
  </div>
</div>

Here, it becomes immediately clear the intended behavior. The <input> tag’s value is wrapped in double curlybraces, thus bound to a variable and subject to change. The inner <div> does *something* when clicked. If we want to know what, we are certain it’s hidden in a function called popup.

Taking a look at the controller:

$scope.inputText = "don't click";
$scope.popup = function () {
  alert("popup");
}

The behavior being explicitly stated within the HTML is called the ‘Declarative Approach’ of Angular. It means that the HTML specifies pretty much all of the behaviors that interact with it, making it easy to understand what happens to each tag. As you use Angular, you’ll find it becomes impossible to obfuscate the logic as I did in the jQuery example above.

As I developed in Angular, I felt the urge to utilize jQuery within my project, but as I learned the ‘Angular Way’, I discovered that less and less I even needed to.

After a short while, I found there’s rarely ever a need to utilize ‘id’ attributes or use classes for use beyond styling.

Ultimately, I failed the No jQuery Challenge (I used the jQuery cookie parser). I don’t actually advocate avoiding jQuery for an angular application, as they’re entirely compatible libraries and jQuery has multitudes of advantages. However, I did find it to be a useful mindset to adopt where, every time I considered using a jQuery selector I asked myself, “Can I do this without jQuery?” I end up discovering that Angular provides for so many great and extensible ways of solving our problems.

The roadblock to learning (two) new things

I used to fear learning. When I was an adolescent, I would go out of my way to avoid learning topics I didn’t consider useful. It must have set me back developmentally by years had I been more inquisitive. Why would young me restrict myself in such a way?

Because I heard the idea that your brain can become ‘filled’ and consequently slows in skills acquisition and memory retention.

A catch 22, I know; to be smart, I must resist learning. While there is some validity to the idea, it’s utterly bunk. Why?

Because when your brain reaches capacity for one thing, it will (nearly) forget another. For me to explain, let me relate a personal tale from these adolescent years.

I played clarinet in highschool. The most ‘dope’ instrument on the symphonic block. I kept at it my whole highschool career, and got pretty good. So good, in fact, that my band director asked me if I wanted to join the school Jazz band. I was stoked; the band had a good reputation, and more importantly, an opportunity to learn the fundamentals of improvisation.

But there was one issue. I told my band director “Clarinet isn’t a Jazz instrument.” “Oh,” he told me. “No worries, just practice this over the summer.” He gave me a 15 lb, 4″ tall baritone saxophone. It sounded like a blow-horn on a mississippi cargo barge. And practice I did.

Over the school year, I had a blast. I performed my first fully improvised solo to an audience of a hundred, learned all about music and chordal theory, even picked up Piano on the side. My young brain was saturated.

One day, I went to play a clarinet. I put my lips on the mouthpiece, and blew. Nothing happened. Not a single sound came out. Trying harder only made a squeaking noise. I was confused; Clarinet and Saxophones are nearly identical in operation. Every day, I would set my Sax down after Jazz Band, and pick up a Clarinet during Symphonic band. And every day, I would spend that hour making no noise on that cursed instrument.

Somehow, in expanding my skillset , I’d crippled my previous abilities. I literally forgot how to play the Clarinet.

If the story ended here, it would a tragic tale to the limits of the human brain. But it doesn’t. It took my nearly six months of effort, more effort – I’m tempted to claim – than my first time learning the Clarinet, to finally produce sound from that instrument. Once I got the hang of it, my original talent instantly came back.

A simple mental roadblock prevented me from recalling my skills. But better than that, I found I had become far better at manipulating the sounds of the Clarinet using my mouth – the thing that had been holding me back. Reeded instruments of all kinds felt more natural to me. It took my a while, but once my brain acclimated to the variation between Clarinet and Saxophone, I became a master at the entire range of technique.

I feel that this principle applies to many talents in life. In learning one thing, you find yourself to be less certain of what you knew before. And uncertain you will remain, until you put in the effort to revisit your old talents. This stumbling block deters many people from reaching expertise. But if you overcome this, you will find mastery reaching beyond your experience.

Universal jquery enter-key binding for any function

var enterkey = function (jquery_obj, func, args) {
 jquery_obj.bind('keypress', function(e) {
  if (e.keyCode==13 && e.shiftKey==false) {
   e.preventDefault();
   func.apply(this, args);
  }
 });
}

This little snippet of code is cleverly designed to allow you to bind any page, textbox, button, with a function that will trigger the moment the enter-key is pressed. Here’s an example:

// Bind the textbox to alert 'Potatomonkies!' when the enterkey is pressed
var potatofunc = function (food, animal, exclamation) { alert(food + animal + exclamation); } 

enterkey($("#textbox"), potatofunc, ['Potato', 'monkies', '!'])

Now, whenever the enterkey is pressed on any element with an id=”textbox”, an alert will show saying “Potatomonkies!”. Easy.

Screen shot 2013-08-30 at 5.43.40 PM

Break it down now.

jquery_obj.bind('keypress', function(e) {

This line is a jquery method for listening for a keypress. Jquery does the heavy lifting, all we need to do is confirm that the keypress is the ‘enterkey’.

  if (e.keyCode==13 && e.shiftKey==false) {
   e.preventDefault();

’13’ is the ascii code for carriage return, IE., the enterkey. It’s convention, when writing in a textbox, to allow the user to hold the shiftkey down when pressing enter to put in an actual new-line instead of submitting. If shift isn’t held down, e.preventDefault() is there to stop the newline from writing.

Now the fun part.

   func.apply(this, args);

function.apply() is a method for manually calling function(), while providing the arguments as a list.

var potatofunc = function (food, animal, exclamation) {
 alert(food + animal + exclamation);
}

The function potatofunc demands three arguments, yet our func.apply(this, args); has only two, and the first argument this appears to do nothing.

This is because the arguments passed to potatofunc was provided when we called bound the enterkey function to potatofunc, as shown below:

var enterkey = function (jquery_obj, func, args)

enterkey($("#textbox"), potatofunc, ['Potato', 'monkies', '!'])

The function enterkey, as the first argument, is given the jquery of items with an id=textbox; the function potatofunc which now triggers on the enterkey as second; and then args, which contains the text to be displayed, as a list of strings.

func.apply(this, args) automatically takes the list [‘Potato’, ‘monkies’, ‘!’] and expands them as the parameters given to potatofunc.

The this in func.apply(this, args) does… well… nothing. It can easily be written as:

func.apply("cats and dogs", args);

And it’ll still work just fine. I’ll leave it up to you to figure that out. 😉

Entrepreneur’s Crucible

Many wannabe entrepreneurs (lookin’ at myself) have grandiose visions of their finished products, complete with bells and whistles. Yet any programmer or engineer who has begun a project understands that the process is not a destination; that there is no final product, only a current iteration.

I was speaking with my friend Scott. We began discussing what it takes to create a project from start to finish. One observation we both agreed upon was that, for any project, the best route is often easiest.

Criticisms aside it’s preferable to have a product that works and then improve upon it over time. If you have a working prototype, much of the actual business aspects open up: You can build a user base, you can showcase your project and acquire shareholders, but most importantly, you can begin to believe that what you’re doing makes sense.

With this in mind we noted that every product out there has probably been invented in the minds of many hopeful businessmen; why they didn’t complete their product was because they lacked was an understanding of the steps necessary to finally create the product.

You see at every given moment there is a suite of tools available. In software there are libraries, languages, and third party plug-ins that can turn a complex problem into a simple one.

Imagine for example that you can create a successful web-application by stitching together a suite of libraries already available online, with minimal coding on your own part. This is the ideal, putting in minimal work for the greatest reward. Paradoxically, it’s also why it’s the least likely as somebody as lazy as yourself may have jumped on the bandwagon before you.

If you look at Apple’s business model over the last decade you can note that the basic concepts of their products have already existed: RIM released the first Blackberry in 1999, Palm introduced their web browsing phone Kyocera 6035 in 2001. Yet the Iphone continues to dominate the smartphone market with its intuitive operating system and reliable design. All it took was for Steve Jobs to wait until the touchscreen, microprocessor, and battery technologies were perfected, and he unveiled a product that can fit in your pocket, browse the web, take calls, and run virtually any app you write for it.

Its tempting to come up with an idea of what you want, and try and find the components to build it up, but this may be the wrong approach. What Jobs understood was the Entrepreneur’s Crucible: Every product is built from its parts; It is the entrepreneur’s task to understand the tools, their strengths and weaknesses, and decide the product that is best for those tools.