Let's break down your code:
var a = "1", // string
b = 1; // number
console.log(a + b);
// a is a string and b is a number
// read from left to right
// string first, so when + goes to concatenate the two variables, you get
// a + b.toString() == "1" + "1" == "11"
console.log(b + a);
// same thing as above because of the .toString() method
// except the + operator sees number + string (versus string + number)
// however, this still casts the number to a string, since that's how
// strings and numbers are concatenated
console.log(a + b + b)
// same as above
// read from left to right
// string is encountered first, so everything after it is cast to a string
// "1" + b.toString() + b.toString() == "1" + "2" + "2" == "122"
// if you want it to be 12, you need to do
// console.log(a + (b + b))
console.log(b + b + a)
// the first + operator sees two integers, so they get added together first
// now it's console.log(2 + a)
// so (2).toString() + a == "2" + "1" == "21", if you follow the logic
// from the second example
b + bis encountered first, it's evaluated as addition, then concatenated with thea. You can look at the behavior here: es5.github.io/#x11.6.1