First of all if you're a teaching assistant at a university then you should tell your professor not to teach JavaScript as an introductory language to students. The reason is that JavaScript is:
- Ambivalent about the kind of a language it wants to be: functional vs object-oriented.
- Too unintuitive: many a times it doesn't behave the way you would expect it to.
- Too verbose: there are too many syntactical elements diverting your attention.
JavaScript is not a suitable introductory language. It's not even a suitable production language which is why we have LiveScript and other compile-to-javascript languages.
Since you're a teaching assistant I would highly recommend that you read Bret Victor's amazing blog post on Learnable Programming. It describes the constituents of a good introductory programming language.
Anyway, I digress. Coming back to the original question, "Literal vs Constructor notation for primitives, which is more proper for starters?" This question is a no-brainer. You know the answer: literals.
I surmise that your professor is trying to teach the following point to the students:
Everything in JavaScript is an object.
Now while it's ideal to think about everything in JavaScript as an object this ideal is too far-fetched. Primitives are not objects. Primitives consist of:
- Undefined.
- Null.
- Booleans.
- Numbers.
- Strings.
I think your professor is confusing JavaScript with Java which advocates that everything is an object (which is actually not true because you still do have primitives in addition to classes, interfaces, etc.)
JavaScript is more object-oriented than Java simply because everything (except for primitives) is an object. You don't have classes in JavaScript. Objects simply inherit from other objects.
On a sticky side note here's a good analogy to explain the difference between primitive vs reference values to students: Primitive value vs Reference value.
Now although you do have primitives in JavaScript you also have wrapper objects for these primitives (i.e. Boolean
, Number
and String
constructors) so as to treat them as objects.
These wrappers expose several useful utility methods. For example you could do: 42..toString(2)
to get the value of 42
in binary as a string. As you can see JavaScript coerces the primitive value 42
into a Number
object automatically when you call a method on the primitive. Hence it makes no sense to create wrapper objects for primitives explicitly. Read The Secret Life of JavaScript Primitives.
In fact if you really wanted a wrapper object instead of a primitive (for performance reasons) the I would do it as follows:
Object.prototype.getObject = function () {
return this;
};
var yes = true.getObject();
var answer = 42..getObject();
var greet = "hello".getObject();
This actually makes more sense to me. You're taking a primitive, coercing in into an object and returning the coerced reference value. By the way, 42
is an allusion to The Hitchhiker's Guide to the Galaxy.
Beside being more succinct another good reason to use literals over wrapper objects is mathematical equivalence. As you described in your question it's desirable to be able to compare two values for mathematical equivalence. Objects break mathematical equivalence. Since objects have a distinct identity two mathematically equivalent objects may not be logically equivalent. For example:
console.log(new Number(42) === new Number(42)); // false
To solve this problem you need to convert the numbers to primitives using valueOf
:
console.log(new Number(42).valueOf() === new Number(42).valueOf()); // true
It's really asinine to write code like this. Why circumscribe yourself to such unnecessary hacks when you could write clean understandable code?
console.log(42 === 42); // true
Everyone know thats 42
is indeed 42
but not many beginners would understand why two objects which are mathematically equivalent are logically distinct.
To summarize, when you're teaching somebody how to program you need to make sure that your code is intuitive (i.e. it shouldn't work in unexpected ways). If it doesn't work the way you would expect it to work then you're doing something wrong. You'll end up struggling with the language instead of writing useful programs.