What you're doing wrong
You're setting it to undefined
: it's a value in itself. You shouldn't be defining it at all for it to work:
// base object
function Animal (nameArg, typeArg) {
if (nameArg) this.name = nameArg;
if (typeArg) this.type = typeArg;
// could be added to prototype, it's the same for each instance
this.sayHello = function () { console.log("Hello my name is " + this.name + " and I am an " + this.type); }; // don't use commas here, use the + operator instead
}
// Setting defaults
Animal.prototype.name = "Anonymous";
Animal.prototype.type = "Animal";
var cat = new Animal(); // passing no arguments to constructor
cat.sayHello(); // now gives correct result ("Hello my name is Anonymous and I am an Animal")
//instantiating an animal WITH argguments passed in
var lion = new Animal("Jimmy", "Lion"); // always worked
Why this is the case
There's actually a difference between a variable set to undefined and a variable never defined, funnily enough - yet another of JavaScript's common quirks. To tell the difference between an undefined variable and one never defined, take this example:
var foo = { x: undefined };
console.log('x' in foo); // true, x has been defined as "undefined"
console.log('y' in foo); // false, foo.y has never been defined
Arguments in JavaScript default to undefined
, similar to when variables are initially defined without setting a value to them or being explicitly set to undefined
:
function test(arg)
{ console.log(arg); // undefined
console.log(doesNotExist); // ReferenceError: doesNotExist is not defined
}
test(); // run and see
By assigning to it, JavaScript keeps a record of it being assigned to, and therefore doesn't look up the prototype chain to see whether the property exists or not (reference).