1. The Name. JavaScript is NOT Java
We'll start with a fun jab at the name choice. While it was originally
called Mocha, and then LiveScript, it was later changed to JavaScript.
According to history, its similarities to the name Java was the result of a
collaboration between Netscape and Sun, in exchange for Netscape bundling the
Java runtime within their popular browser. It's also been noted that the name
came, almost as a joke, due to the rivalry between LiveScript and Java for client-side
scripting.
Nevertheless, it resulted in thousands of “JavaScript has nothing to do with Java” comments in forums across the web!
2. Null is an Object?
Consider this…
console.log(typeof null); // object
3. NaN !== NaN
NaN, as we’d expect refers to a value that is not a legal number. The problem is that NaN isn’t equal to anything…including itself.
console.log(NaN === NaN); //false
This should be wrong. Instead, if you want to determine if a value is indeed NaN, you can use the isNaN() function.
Update: after reading through some of the brilliant comments, particularly the ones relating to NaN being similar to infinity, it then makes perfect sense that NaN would not equal itself. But it can still be confusing. Refer to the comments for an in depth discussion on this!
4. Global Variables
The dependence upon global variables is widely considered to be far and away the worst part of JavaScript. For simple projects, much like the quick tips on this site, it doesn’t truly make a difference. However, the real burden of globals come into play when you begin referencing multiple scripts, without any knowledge of how they’re created, or named. If they happen to share the same name as one of your variables, your program is going to throw some sort of error.
“The problem with JavaScript isn’t just that it allows them (global variables), it requires them.” – Crockford
5. User-Agent Strings Report Mozilla. Ever Wonder Why?
Alright – this one isn’t the fault of JavaScript. I cheated a bit. It’s because of the browser vendors. Having said that, user-agent string detection is very common in JavaScript; so it’s important to know what you’re dealing with. It probably doesn’t belong in this list, but who cares! It’s good to know.
This one isn’t as much a mistake as it was an unavoidable decision. For example, open Safari, access the Web Inspector, and log the user agent string into the console.
console.log(navigator.userAgent); // Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-us) AppleWebKit/531.21.8 (KHTML, like Gecko) Version/4.0.4 Safari/531.21.10
Note that first string of characters: Mozilla/5.0. Why would Safari identify it as a Mozilla based browser? Though it later correctly identifies itself, that still doesn’t explain why they’d bother to mislead programmers. In fact, you’ll find that most browsers identify themselves as Mozilla. The answer goes back a decade, and is, again, less an error, and more an unavoidable circumstance.
For those unfamiliar, a user-agent string is simply meant to identify the browser and its version. As an example, the first ever browser, Mosaic, had a user-agent string that looked like so:
This makes perfect sense. And when Netscape came onto the scene, they kept Mosaic’s usage, and also added an encryption type section.
So far so good. The problems came into play when – wait for it – Internet Explorer 3 was released. Keep in mind that, when they launched, Netscape was the most popular browser available. In fact, many servers and programs were already implementing user-agent detection in order to identify Netscape. Though this is a highly debated topic today, back then, it wasn’t much of an issue. If IE had used their own user-agent string, it would have looked something like this:
MSIE/3.0 (Win95; U)
This would have left them at a huge disadvantage, because Netscape was already being identified by many servers. As such, the developers decided to incorrectly identify the browser as Mozilla, and then append an additional set of information labeling it as Internet Explorer.
Mozilla/2.0 (compatible; MSIE 3.0; Windows 95)
Nowadays, user-agent detection is a last effort, and its considered so precisely for this reason. You’ll find that most browsers followed IE’s lead in identifying themselves as Mozilla. Think of it as a chain reaction.
6. Scope Inconsistencies
Consider the following code:
// Create a function that will call a function with the name equal to parameter fn.
function foo(fn)
{
if (typeof fn === "function")
{
fn();
}
}
// Create an object with a property and a method.
var bar =
{
barbar : "Hello, World!",
method : function()
{
alert(this.barbar);
}
};
bar.method(); // Alerts Hello, World!
foo(bar.method); // If we call the foo function add pass the "bar.method" method, it somehow alerts
"undefined."
foo(function() { bar.method(); }); // alerts Hello, World, after
The reason why foo(bar.method) does not render the same result is because the method function will be called as a method of the window object, rather than bar. To fix this, we must call bar.method() from within the passed anonymous function.
*Thanks so much to Jeremy McPeak for notifying me of this error.
7. The Use of Bitwise Operators
JavaScript shares many similarities with Java – one of them being the set of bitwise operators.
- & – and
- | – or
- ^ – xor
- ~ – not
- >> – signed right shift
- ??? – unsigned right shift
- << – left shift
This is why you can get away with using & for “and”, and | for “or” – even though you should be using && and ||.
8. Too Many Falsy/Bottom Values
Maybe this isn’t specifically an error in JavaScript, but it certainly makes the learning process, especially for beginners, a tough one. Values like null, false, and undefined almost mean the same thing, but there are differences that can be confusing to understand.
Falsy Values
To test, open up the console in Firefox, and find the boolean of the following items.
!!(false); // false
!!(''); // false
!!(null); // false
!!(undefined); // false
!!(NaN); // false
More than an error, this many falsy values is just confusing!
9. It Can’t Do Arithmetic
Okay, okay – I’m 99% teasing with the heading above. But JavaScript does have a few minor issues when working with decimals, for example, things like money transactions. For example, open up your console, and log “.2 + .4″. We would expect it to display “.6″, correct? Well it does, and it doesn’t!
10. Code Styling Isn’t your Choice!
When it comes to your coding style, it’s exactly that: your style. Some people prefer to place their curly braces on the same line as the control, others prefer that it goes on its own.
return
{
foo : bar
};
// braces on their own line
return
{
foo : bar
};
foo : bar
};
// braces on their own line
return
{
foo : bar
};
I learned this particular example from a lecture that Doug Crockford gave around a year ago. Consider the return statement from above. Believe it or not, they ARE NOT equal. Don’t believe me? Try this out. Add the following to some HTML page.
{
return
return
{
a : 'b'
};
}
a : 'b'
};
}
(); alert(foo.a); // b
{
a : 'b'
};
So why does JavaScript do this? It’s because of something called “semicolon insertion.” Essentially, JavaScript will attempt to correct our bad coding. If, for instance, it thinks that you’ve left off a closing semicolon, it’ll go ahead and add it on for you. Though this was originally intended to be a convenience, especially for newer JavaScripters, it’s actually a very bad thing when you don’t have control over your own code, as demonstrated above.
In our example, there’s no way to determine why foo.a returns “undefined. ” Now that we’re aware of semicolon insertion, the reason it’s undefined is because JavaScript will add a semicolon to the end of the return statement.
{
a : 'b'; // It'll add a semicolon here as well, because it doesn't realize that this is an object.
};
credit : net.tutsplus.com
No comments:
Post a Comment