April 28, 2020

Two things that are vital to understand working with Javascript

In brief, you need to have a solid understanding of functions and objects. In particular you need to understand the Javascript syntax for working with them, and common idioms used by the Javascript culture.

Functions

The idea is easy and basic. You define a function, then you "call" it, perhaps passing arguments, whenever you want to use it. Two aspects of Javascript are somewhat unique with regard to functions. One is that functions can be used as values and passed around in variables. The other is that it is exceedingly common to use nameless i.e. "anonymous" functions.

The common case is like most other programming languages.

function pork ()
{
    return "pig";
}

var animal = pork ();
This should present no surprises. We have a function that returns a fixed string value. We call it by giving the name of the function followed by an empty set of parenthesis (since this function takes no arguments). The end result is that the variable "animal" will contain the string value "pig".

Consider the folowing line of code:

var animal = pork;
Here we omit the empty parenthesis after "pork". Javascript is perfectly happy with this. In fact what it does is to set the variable "animal" to be a reference to the function "pork", establishing in essence a synonym. We could then do this:
console.log ( animal() );
That's right, we can now treat the variable animal just like it was a function, and we will get the value "pig" printed on the console. All this will surprise many people who are familiar with other computer languages.

The other interesting thing about functions in Javascript is that Javascript allows for anonymous functions. These are often used when setting up callbacks. Without using anonymous functions we could write code like this:

function handler ()
{
    console.log ( "somebody clicked!" );
}

xyz.onclick = handler;
But we could instead use an anonymous function and condense all this (as is commonly done) like the following:
xyz.onclick = function () {
    console.log ( "somebody clicked!" );
}
The effect is exactly the same. We could even put it all on one line. Which is better? There are arguments both ways, see my section on "style" at the end of this page. The main thing is you should get used to both ways of doing things and understand that they are equivalent.

Objects

Books upon books are written about objects. The topic is made frightening and given an almost "holy" virtue by some. Forget all of that. Forget about all you hear about inheritance and everything involved with that. Almost all of the time when you use objects in Javascript you don't need any of that and things are really simple.

Just think of an object as a bag or package with a bunch of things in it. Those things have names, as if each is a variable. If you think of an object as a collection of things where each thing has a name and a value, you are good to go.

Any old variable can hold an object (since Javascript is a typeless language) so we could set up an object like this:

var my_object = { height: 5, weight: 100 };
There you go, we have made an object! It has two things (often called properties), one called weight and the other calleded height. We are just rounding off height to the nearest foot for this example, because we are lazy and want to keep this simple. Sometimes we want to hand an object to a function, and this is a handy way to hand a bundle of things all at once. We could do this:
calc_bmi ( my_object );
Here we pass our object to a function (that perhaps calculates BMI -- body mass index). Here we have the object in a variable and use the name of the variable to hand the object to the function. But there is another way to do things that is a lot like the anonymous function business we discussed above.
calc_bmi ( { height: 6, weight: 190 } );
This works exactly the same as the example above (although we have different values for the properties of the object, for no particular reason.

Callbacks

A lot of Javascript programming is "event driven". So you call some function and tell it that when something happens, a function you provide ought to be called. This is called registering a callback. Some examples are:
button.onclick = button_handler;
socket.on('data', data_handler );
I make it a convention to name my callback handling functions "xyz_handler". I also tend to avoid using anonymous functions, but that is a matter of style, and so is my naming convention I suppose.

You never know, nor should you care, when a callback might happen. Some people are uncomfortable with this and whine about "callback hell". Callbacks are your friends and a great way to do network programming or user interfaces.

Teaching yourself

I am tossing this in as a freebee to reward those who have endured this far. How do you learn to program? How do you learn a new programming language? How do you learn anything? I am convinced that we have to teach ourselves.

This is true even if you are in a lesson or a class. I used to teach people to ski, and all I did was present an opportunity to learn. That is true of a class in programming also. It can be a good or bad opportunity. One advantage of a class is that it keeps you on a schedule and requires you to master things you might skip over if entirely on your own. Regardless, here are my tips.

Challenge yourself in small ways. Invent your own little projects to prove to yourself that you can understand something. Let each project extend what you know in one specific area. If you are copying examples online, that is not entirely bad, but play with them. Make changes. I advocate the scientific method. State a theory, then devise an experiment to test it, then give it a go. This often reveals areas of misunderstanding and helps you learn.

One of the hardest things to do in the world of software is to take some program written by someone else and make changes to it. Every one has their own style, and there are always things you don't know about why they did what they did. I advocate incremental development. Start with a one line program that prints "Howdy!". Test that, make a small addition and test that. Keep building bit by bit and testing every change. What you absolutely don't want to do is to write a big program, then start testing and debugging.

Here is something to bear in mind when and if you get discouraged. When you are learning, one stage of the learning process is when a bunch of new concepts have been dumped into your mind. Your mind has not found proper places for them yet and related them one to another. So you feel confused, overloaded, maybe discouraged, but this is just a normal part of the process. When you are always learning new things, you get used to this phase and aren't discouraged by it, maybe even expect and welcome it.

Style

It is worth talking about programming style. I am not (as some do) going to get on my high horse and promote some one true style like a style nazi. I am going to talk about some pros and cons of different styles as well as indicate some opinions I have developed.

Above all, style should aim for clarity. Most often this will help you rather than someone else. It will help you when you are first writing and debugging your code. It will especially help you when you come back to your own code years later. You don't want to be asking yourself, "why did I write a mess like this?".

Two pitfalls to avoid are aiming for efficiency or for brevity. Aiming for brevity uses anonymous function and nameless objects whenever possible and sections of code end in a tangle like this:

}));
This is common though in the Javascript culture and you may as well get used to it. Above all, you should understand what is going on and why each of those marks needs to be there. Studying my sections above on functions and objects should help.

Aiming for efficiency is almost always misplaced energy. Rarely if ever will writing some convoluted code yield faster code. Don't fool yourself into thinking that compact code is more efficient.

For many programs, efficiency is not any kind of issue at all. The program is going to run in a small fraction of a second, so make it clear and easy to understand.


Have any comments? Questions? Drop me a line!

Adventures in Computing / tom@mmto.org