All of those results make sense. > "print( (new String('foo') === new String('foo')))" > false
Those are two different objects, even though they have the same value; object1 !== object2 by definition of the === operator. In real code, I have never seen a good reason to use 'new String()' rather than a primitive string. There are are several situations where 'new String()' will break code that seems like it should work perfectly well--for example, in an eval() or switch statement. "print('foo' === 'foo')" true Two primitives with the same type and value are === as well as == > "print(typeof someUndefined == 'fuzzyDuck')" > false typeof someUndefined is 'undefined', and 'undefined' != 'fuzzyDuck' > "print(typeof someUndefined === 'fuzzyDuck')" > false As above; same type (string) but different values. > "print(typeof someUndefined == 'undefined')" > true typeof someUndefined is 'undefined' (string) so the two are equal. > "print(typeof someUndefined == undefined)" > false The string 'undefined' is never equal to the intrinsic undefined value.