• Martin Thoma
  • Home
  • Categories
  • Tags
  • Archives
  • Support me

JavaScript: WTF?!?

Contents

  • Weak typing
  • Weak typing and string concatenation
  • Automatic semicolons
  • Truth table
  • The truth
  • Date
  • Integer overflow
  • Function parameters
  • Global variables
  • See also

JavaScript is THE web programming language. It gets interpreted by your browser and web applications like Google Mail, Google Maps and Facebook make heavy use of them. Almost always, when you see something working smoothly / interactive, you see JavaScript in action.

But JavaScript has a lot of "features" which are ... well, I don't have words for those. Just continue reading.

Most of the following content is from a StackOverflow question Strangest language feature

Weak typing

Example

console.log(3..toString());

Output

'3'

Explanation 3. is a floating point and can get converted to a string. But 3.toString() gives

SyntaxError: Unexpected token ILLEGAL

Weak typing and string concatenation

Example

console.log('5' + 3);
console.log('5' - 3);

Output

'53'
2

Explanation JavaScript automatically converts datatypes and + is used for string concatenation and for addition.

In the first case, as the first datatype is a string and + is defined for strings as concatenation, JS converts 3 to '3' which results in the string '53'.

In the second case, - is only defined for subtraction so '5' gets converted to a number (int? float? I don't know. I guess int.)

Automatic semicolons

Example 1

function test() {
    return
    {
        id : 1338,
        title : 'This is a test'
    };
}

console.log(test());

Example 2

function test() {
    return
        2 + 2;
}

console.log(test());

Output 1

Uncaught SyntaxError: Unexpected token :

Output 2

undefined

Explanation JS adds a ; at every line end. Automatically. You can't prevent it.

Please note that the second output is no error! It has a (valid) return value of undefined.

Truth table

Example

console.log("------- 0 == XYZ ---------");
console.log(0 == 0);
console.log(0 == false);
console.log(0 == '');
console.log(0 == null);
console.log(0 == undefined);
console.log(0 == " \t\r\n");
console.log(0 == '0');
console.log(0 == 'false');
console.log("------- false == XYZ ---------");
console.log(false == false);
console.log(false == '');
console.log(false == null);
console.log(false == undefined);
console.log(false == " \t\r\n");
console.log(false == '0');
console.log(false == 'false');
console.log("------- '' == XYZ ---------");
console.log('' == '');
console.log('' == null);
console.log('' == undefined);
console.log('' == " \t\r\n");
console.log('' == '0');
console.log('' == 'false');
console.log("------- null == XYZ ---------");
console.log(null == null);
console.log(null == undefined);
console.log(null == " \t\r\n");
console.log(null == '0');
console.log(null == 'false');
console.log("------- undefined == XYZ ---------");
console.log(undefined == undefined);
console.log(undefined == " \t\r\n");
console.log(undefined == '0');
console.log(undefined == 'false');
console.log("-------  \t\r\n == XYZ ---------");
console.log(" \t\r\n" == " \t\r\n");
console.log(" \t\r\n" == '0');
console.log(" \t\r\n" == 'false');
console.log("------- '0' == XYZ ---------");
console.log('0' == '0');
console.log('0' == 'false');
console.log("------- 'false' == XYZ ---------");
console.log('false' == 'false');
console.log("--------------------");
console.log("-------  XYZ == 0 ---------");
console.log(0 == 0);
console.log(false == 0);
console.log('' == 0);
console.log(null == 0);
console.log(undefined == 0);
console.log(" \t\r\n" == 0);
console.log('0' == 0);
console.log('false' == 0);
console.log("-------  XYZ == false ---------");
console.log(false == false);
console.log('' == false);
console.log(null == false);
console.log(undefined == false);
console.log(" \t\r\n" == false);
console.log('0' == false);
console.log('false' == false);
console.log("-------  XYZ == '' ---------");
console.log('' == '');
console.log(null == '');
console.log(undefined == '');
console.log(" \t\r\n" == '');
console.log('0' == '');
console.log('false' == '');
console.log("-------  XYZ == null ---------");
console.log(null == null);
console.log(undefined == null);
console.log(" \t\r\n" == null);
console.log('0' == null);
console.log('false' == null);
console.log("-------  XYZ == undefined ---------");
console.log(undefined == undefined);
console.log(" \t\r\n" == undefined);
console.log('0' == undefined);
console.log('false' == undefined);
console.log("-------  XYZ == \t\r\n ---------");
console.log(" \t\r\n" == " \t\r\n");
console.log('0' == " \t\r\n");
console.log('false' == " \t\r\n");
console.log("-------  XYZ == '0' ---------");
console.log('0' == '0');
console.log('false' == '0');
console.log("-------  XYZ == 'false' ---------");
console.log('false' == 'false');

Output

== 0 false '' null undefined " \t\r\n" '0' 'false'
0 true true true false false true true false
false true true true false false true true false
'' true true true false false false false false
null false false false true true false false false
undefined false false false true true false false false
" \t\r\n" true true false false false true false false
'0' true true false false false false true false
'false' false false false false false false false true

Explanation Wow. This is fucked up. I've expected that strings compared to anything that is not the string itself evaluates to false.

At least the table is symmetric and the diagonal is true. Please also note that JavaScript has a === operator.

The truth

Example

console.log(2 == [2]);
console.log(2 == [[2]]);

Output

true
true

Explanation At StackOverflow

Date

Example

var futureDate = new Date(2010,77,154);
console.log(futureDate);
console.log(futureDate.getYear());

Output

Tue Nov 01 2016 00:00:00 GMT+0100 (CET)
116

Explanation 77 months and 154 days from the 0th day of 0th month of 2010

You should use getFullYear() instead of getYear(), as the later one returns year - 1900 (Why? When is this useful?)

Integer overflow

Example

console.log(111111111111111111111);

Output

111111111111111110000

Explanation It's ok that JavaScript fails at handling this integer. I think it converts this to a float, but I'm not sure about that. But no matter what it does here, it doesn't throw an error. That's bad. How is a developer supposed to know in a big application know when something went wrong?

Function parameters

In Javascript, declaring the parameters a function accepts is only a convenience to the programmer. All variables passed through the function call are accessible by the keyword arguments. So the following would alert "world":
function blah(){
    alert(arguments[1]);
}

blah("hello", "world");

Source on StackOverflow

Global variables

Example

var a = 12;

function test() {
  a = 1337;
}
test();
console.log(a);

Output

1337

Explanation When you forget to use var inside of test() you might accidentally use a global variable.

See also

Do you know some more JavaScript WTFs?

You might also be interested in PHP: A strange language

Published

Jun 26, 2013
by Martin Thoma

Category

Code

Tags

  • JavaScript 7

Contact

  • Martin Thoma - A blog about Code, the Web and Cyberculture
  • E-mail subscription
  • RSS-Feed
  • Privacy/Datenschutzerklärung
  • Impressum
  • Powered by Pelican. Theme: Elegant by Talha Mansoor