Did You Know: Secrets and Facts about Javascript
Did You Know: Secrets and Facts about Javascript

JavaScript – The world’s most misunderstood programming language. JavaScript, also known as Mocha, or LiveScript, or JScript, or ECMAScript, is one of the world’s most popular programming languages. Virtually every personal computer in the world has at least one JavaScript interpreter installed on it and in active use.

Despite its popularity, few know that JavaScript is a very nice dynamic object-oriented general-purpose programming language. What can’t you do with JavaScript? Though it is popularly known as a Client Side language, but even you can send Server request with it. So why is this language so misunderstood?

The Java- prefix suggests that JavaScript is somehow related to Java, that it is a subset of Java. It seems that the name was intentionally selected to create confusion. JavaScript is not interpreted Java. Java is interpreted Java. JavaScript is a different language. JavaScript has a syntactic similarity to Java, much as Java has to C. But it is no more a subset of Java than Java is a subset of C. It is better than Java in the applications that Java was originally intended for. JavaScript was not developed at Sun Microsystems, the home of Java. JavaScript was developed at Netscape. It was originally called LiveScript, but that name wasn’t confusing enough. The – Script suffix suggests that it is not a real programming language, that a scripting language is less than a programming language. But it is really a matter of specialization.

The first versions of JavaScript were quite weak. They lacked exception handling, inner functions, and inheritance. In its present form, it is now a complete object-oriented programming language. But many opinions of the language are based on its immature forms. No programming language is perfect. JavaScript has its share of design errors, such as the overloading of + to mean both addition and concatenation with type coercion, and the error-prone with statement should be avoided. The reserved word policies are much too strict. Semicolon insertion was a huge mistake, as was the notation for literal regular expressions. These mistakes have led to programming errors, and called the design of the language as a whole into question.

Some of the earlier implementations of JavaScript were quite buggy. This reflected badly on the language. Compounding that, those implementations were embedded in horribly buggy web browsers. The official specification for the language is published by ECMA. The specification is of extremely poor quality. It is difficult to read and very difficult to understand. This has been a contributor to the Bad Book problem because authors have been unable to use the standard document to improve their own understanding of the language.

Another question is: Is JavaScript object-oriented? It has objects which can contain data and methods that act upon that data. Objects can contain other objects. It does not have classes, but it does have constructors which do what classes do, including acting as containers for class variables and methods. It does not have class-oriented inheritance, but it does have prototype-oriented inheritance.

The two main ways of building up object systems are by inheritance and by aggregation. JavaScript does both, but its dynamic nature allows it to excel at aggregation. Some argue that JavaScript is not truly object oriented because it does not provide information hiding. That is, objects cannot have private variables and private methods: All members are public. But its true and many people don’t know that JavaScript objects can actually have private variables and private methods. Some argue that JavaScript is not truly object oriented because it does not provide inheritance. But its also true that JavaScript supports not only classical inheritance, but other code reuse patterns as well. So, JavaScript is an OOPL.

Now lets look into some of its beautiful features and well-kept secrets. JavaScript is like a beautiful woman, the more you uncover her, the more you get to know about her beauty. This article will give you insight into how these curiosities can be useful to your code.

1. Null is an Object
Null is apparently an object, which, as far as contradictions go, is right up there with the best of them. Surely, the definition of null is the total absence of meaningful value. But in JavaScript Null has some respect.

alert(typeof null); //alerts 'object'

Despite this, null is not considered an instance of an object. This brings us back to sanity, because if null is the absence of value, then it obviously can’t be an instance of anything. Hence, the following evaluates to false:

alert(null instanceof Object); //evaluates false

2. NaN is a number
NaN —  which is abbreviated from “not a number” — being a number! Moreover, NaN is not considered equal to itself! Does your head hurt yet?

alert(typeof NaN); //alerts 'Number'
alert(NaN === NaN); //evaluates false

In fact NaN is not equal to anything. The only way to confirm that something is NaN is via the function isNaN().

3. An Array with no Keys == False
Here’s another much-loved JavaScript oddity:

alert(new Array() == false); //evaluates true

JavaScript, every non-boolean value has a built-in boolean flag that is called on when the value is asked to behave like a boolean; like, for example, when you compare it to a boolean.
Because apples cannot be compared to pears, when JavaScript is asked to compare values of differing data types, it first “coerces” them into a common data type. False, zero, null, undefined, empty strings and NaN all end up becoming false — not permanently, just for the given expression. An example to the rescue:

var someVar = 0;
alert(someVar == false); //evaluates true

Here, we’re attempting to compare the number 0 to the boolean false. Because these data types are incompatible, JavaScript secretly coerces our variable into its truthy or falsy equivalent, which in the case of 0 is falsy.
Empty arrays still are curious things: they actually evaluate to truthy but, when compared against a boolean, behave like a falsy. Confused yet? Another example perhaps:

var someVar = []; //empty array
alert(someVar == false); //evaluates true
if (someVar) alert('hello'); //alert runs, so someVar evaluates to true

To avoid coercion, you can use the value and type comparison operator, ===, (as opposed to ==, which compares only by value). So:

var someVar = 0;
alert(someVar == false); //evaluates true – zero is a falsy
alert(someVar === false); //evaluates false – zero is a number, not a boolean

If you really want to sink your teeth into what happens internally when JavaScript is asked to compare two values, then check out section 11.9.3 of the ECMA-262 document specification.

4. replace() can accept a Callback Function
This is one of JavaScript’s best-kept secrets and arrived in v1.3. Most usages of replace() look something like this:

alert('10 13 21 48 52'.replace(/d+/g, '*')); //replace all numbers with *

This is a simple replacement: a string, an asterisk. But what if we wanted more control over how and when our replacements take place? What if we wanted to replace only numbers under 30? This can’t be achieved with regular expressions alone (they’re all about strings, after all, not maths). We need to jump into a callback function to evaluate each match.

alert('10 13 21 48 52'.replace(/d+/g, function(match) {
return parseInt(match) < 30 ? '*' : match;
}));

For every match made, JavaScript calls our function, passing the match into our match argument. Then, we return either the asterisk (if the number matched is under 30) or the match itself (i.e. no match should take place).

5. Regular Expressions: More that just match and replace
Many intermediate JavaScript developers get by just on match and replace with regular expressions shortly known as RegEx. But JavaScript defines more methods than these two.
Of particular interest is test(), which works like match except that it doesn’t return matches: it simply confirms whether a pattern matches. In this sense, it is computationally lighter.

alert(/w{3,}/.test('Hello')); //alerts 'true'

The above looks for a pattern of three or more alphanumeric characters, and because the string Hello meets that requirement, we get true. We don’t get the actual match, just the result.
Also of note is the RegExp object, by which you can create dynamic regular expressions, as opposed to static ones. The majority of regular expressions are declared using short form. That way, though, you can’t reference variables, so making dynamic patterns is impossible. With RegExp(), though, you can.

function findWord(word, string) {
var instancesOfWord = string.match(new RegExp('b'+word+'b', 'ig'));
alert(instancesOfWord);
}
findWord('car', 'Carl went to buy a car but had forgotten his credit card.');

Here, we’re making a dynamic pattern based on the value of the argument word. The function returns the number of times that word appears in string as a word in its own right (i.e. not as a part of other words). So, our example returns car once, ignoring the car tokens in the words Carl and card. It forces this by checking for a word boundary (b) on either side of the word that we’re looking for.
Because RegExp are specified as strings, not via forward-slash syntax, we can use variables in building the pattern. This also means, however, that we must double-escape any special characters, as we did with our word boundary character.

6. Scope can be faked!
The scope in which something executes defines what variables are accessible. Free-standing JavaScript (i.e. JavaScript that does not run inside a function) operates within the global scope of the window object, to which everything has access; whereas local variables declared inside functions are accessible only within that function, not outside.

var animal = 'dog';
function getAnimal(adjective) { alert(adjective+' '+this.animal); }
getAnimal('lovely'); //alerts 'lovely dog';

Here, our variable and function are both declared in the global scope (i.e. on window). Because this always points to the current scope, in this example it points to window. Therefore, the function looks for window.animal, which it finds. So far, so normal. But we can actually con our function into thinking that it’s running in a different scope, regardless of its own natural scope. We do this by calling its built-in call() method, rather than the function itself:

var animal = 'dog';
function getAnimal(adjective) { alert(adjective+' '+this.animal); };
var myObj = {animal: 'camel'};
getAnimal.call(myObj, 'lovely'); //alerts 'lovely camel'

Here, our function runs not on window but on myObj — specified as the first argument of the call method. Essentially, call() pretends that our function is a method of myObj (if this doesn’t make sense, you might want to read up on JavaScript’s system of prototypal inheritance). Note also that any arguments we pass to call() after the first will be passed on to our function — hence we’re passing in lovely as our adjective argument.
But JavaScript developers say that they’ve gone years without ever needing to use this, not least because good code design ensures that you don’t need this smoke and mirrors. Nonetheless, it’s certainly an interesting one.
As an aside, apply() does the same job as call(), except that arguments to the function are specified as an array, rather than as individual arguments. So, the above example using apply() would look like this:

getAnimal.apply(myObj, ['lovely']); //func args sent as array

7. Functions can executes themselves
There’s no denying it:

(function() { alert('hello'); })(); //alerts 'hello'

The syntax is simple enough: we declare a function and immediately call it just as we call other functions, with () syntax. You might wonder why we would do this. It seems like a contradiction in terms: a function normally contains code that we want to execute later, not now, otherwise we wouldn’t have put the code in a function.
One good use of self-executing functions (SEFs) is to bind the current values of variables for use inside delayed code, such as callbacks to events, timeouts and intervals. Here is the problem:

var someVar = 'hello';
setTimeout(function() { alert(someVar); }, 1000);
var someVar = 'goodbye';

In several forums invariably its asked why the alert in the timeout says goodbye and not hello. The answer is that the timeout callback function is precisely that — a callback — so it doesn’t evaluate the value of someVar until it runs. And by then, someVar has long since been overwritten by goodbye.
SEFs provide a solution to this problem. Instead of specifying the timeout callback implicitly as we do above, we return it from an SEF, into which we pass the current value of someVar as arguments. Effectively, this means we pass in and isolate the current value of someVar, protecting it from whatever happens to the actual variable someVar thereafter. This is like taking a photo of a car before you respray it; the photo will not update with the resprayed color; it will forever show the color of the car at the time the photo was taken.

var someVar = 'hello';
setTimeout((function(someVar) {
return function() { alert(someVar); }
})(someVar), 1000);
var someVar = 'goodbye';

This time, it alerts hello, as desired, because it is alerting the isolated version of someVar (i.e. the function argument, not the outer variable).

8. Mozilla Firefox reads and returns colors in RGB, not HEX
Its never really understood why Mozilla does this. Surely it realizes that anyone interrogating computed colors via JavaScript is interested in hex format and not RGB. To clarify, here’s an example:

Hello, world!
<script>
var ie = navigator.appVersion.indexOf('MSIE') != -1;
var p = document.getElementById('somePara');
alert(ie ? p.currentStyle.color : getComputedStyle(p, null).color);
</script>

While most browsers will alert ff9900, Firefox returns rgb(255, 153, 0), the RGB equivalent. Plenty of JavaScript functions are out there for converting RGB to hex.
Compare this to style, which reads only style properties that were implicitly set in an element’s style attribute. Also, as you’ll have noticed in the example above, IE has a different method of detecting computed styles from other browsers.
As an aside, jQuery’s css() method encompasses this sort of computed detection, and it returns styles however they were applied to an element: implicitly or through inheritance or whatever. Therefore, you would relatively rarely need the native getComputedStyle and currentStyle.
Miscellaneous

9. 0.1 + 0.2 !== 0.3
This one is an oddity not just in JavaScript; it’s actually a prevailing problem in computer science, and it affects many languages. The output of this is 0.30000000000000004.
This has to do with an issue called machine precision. When JavaScript tries to execute the line above, it converts the values to their binary equivalents.
This is where the problem starts. 0.1 is not really 0.1 but rather its binary equivalent, which is a near-ish (but not identical) value. In essence, as soon as you write the values, they are doomed to lose their precision. You might have just wanted two simple decimals, but what you get, as Chris Pine notes, is binary floating-point arithmetic. Sort of like wanting your text translated into Russian but getting Belorussian. Similar, but not the same.
Solutions to this problem are a favorite on computer science and developer forums.
Converting to integers and calculating on those instead, then converting back to decimals afterward; or tweaking your logic to allow for a range rather than a specific result.
So, for example, rather than,

var num1 = 0.1, num2 = 0.2, shouldEqual = 0.3;
alert(num1 + num2 == shouldEqual); //false
… we would do this:
alert(num1 + num2 > shouldEqual - 0.001 && num1 + num2 < shouldEqual + 0.001); //true

Translated, this says that because 0.1 + 0.2 is apparently not 0.3, check instead that it’s more or less 0.3 — specifically, within a range of 0.001 on either side of it. The obvious drawback is that, for very precise calculations, this will return inaccurate results.

10. Undefined can be Defined
Strange as it might sound, undefined is not actually a reserved word in JavaScript, even though it has a special meaning and is the only way to determine whether a variable is undefined. So:

var someVar;
alert(someVar == undefined); //evaluates true

So far, so normal. But:

undefined = "I'm not undefined!";
var someVar;
alert(someVar == undefined); //evaluates false!

You can also check Mozilla’s list of all reserved words in JavaScript for future reference.

So now are you enlightened enough? Do you have more secrets and facts about JavaScript in your knowledge? Share your thoughts in the comment section.

Till next, happy JavaScripting.

About the author

Scientific History Blog Writer • Art enthusiast and Illustrator • Amateur Photographer • Biker and Hiker • Beer Enthusiast • Electrical Engineer • Chicago

Leave a Reply

Twitter Feed
%d bloggers like this: