^ is XOR, a bitwise operation. On a single bit, the rules are 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 0, and 1 ^ 1 = 0, and you simply extend perform it on corresponding bits when dealing with multi-bit values. The name is short for "exclusive or", and comes from the fact that A ^ B is 1 if and only if either A or B is 1, not both. But, it's more interesting to talk about its other name, ⊕. ⊕ is + but slightly different. You'll notice that the rules for ⊕ are similar to the rules for addition: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, and 1 + 1 = 10. ⊕ is +, except 1 ⊕ 1 = 0; that is, ⊕ is +, except without carrying. This holds for multiple bits: 011 + 001 = 100, because you carry a 1 out of the ones place into the twos place, and then carry a 1 again into the fours place. Then, 011 ⊕ 001 = 010, because you just don't carry.
Now, when doing real addition, when do you carry? In binary, the answer is very simple: you carry a 1 into the next place when there are two 1s in a given place. This is easily understood as a bitwise AND, &. 1 & 1 = 1, and 0 otherwise. For 011 + 001, addition without carrying gives 011 ⊕ 001 = 010, and we can tell we need to carry a 1 out of the ones place because 011 & 001 = 001. The shifting in (a & b) << 1 turns a number "where do I need to carry from?" into "where do I need to add carries?": (011 & 001) << 1 = 010; I need to add a carry bit in the twos place.
So, in getSum, we want to know a + b. We compute the addition without carrying with a ^ b, and we find where we need to add carry bits with (a & b) << 1. Now, we just need to add those two together. Well, we already have a function for adding numbers together; it's called getSum. So, we basically just write function getSum(a, b) { return getSum(a ^ b, (a & b) << 1); }, except we make sure to short-circuit if there is nothing to carry, saving us from infinite recursion.