Evanss
Evanss

Reputation: 23213

Create "default" value for constructor function with prototype?

Ive created a constructor function called Cat. var fluffy is an instance of this.

Ive attempted to set a the default value for the breed to be tabby. However when I log out fluffy breed is undefined.

'use strict';

function Cat(name, age, breed) {
  this.name = name,
  this.age = age,
  this.breed = breed
}

Cat.prototype.breed = "tabby";

var fluffy = new Cat ("Fluffy the 3rd", "4 years");

console.log(fluffy);

Console result:

Object { name: "Fluffy the 3rd", age: "4 years", breed: undefined }

Upvotes: 2

Views: 1214

Answers (3)

Jack Taylor
Jack Taylor

Reputation: 6237

As you are not passing a breed argument to the Cat constructor, JavaScript treats breed as undefined inside the constructor function. The issue is that assigning undefined to this.breed has a subtly different effect than not assigning it at all.

To see the difference, try using delete to remove the property from the fluffy object:

'use strict';

function Cat(name, age, breed) {
  this.name = name,
  this.age = age,
  this.breed = breed
}

Cat.prototype.breed = "tabby";

var fluffy = new Cat ("Fluffy the 3rd", "4 years");
console.log(fluffy.breed); // logs "undefined"

delete fluffy.breed;
console.log(fluffy.breed); // logs "tabby"

To do this with a prototype you would need to use if/then logic in the constructor:

function Cat(name, age, breed) {
  this.name = name;
  this.age = age;
  if (breed) {
    this.breed = breed;
  }
}

It might be easiest to assign the default in the constructor, though.

function Cat(name, age, breed) {
  this.name = name;
  this.age = age;
  this.breed = breed || 'tabby';
}

(Note that this won't allow this.breed to be falsey values like "" or 0, so be conscious of the range of values that you want to allow.)

Upvotes: 0

StackSlave
StackSlave

Reputation: 10617

This is because you have not passed a value to your breed argument, so it's overwriting Cat.prototype.breed = 'tabby' with this.breed = argument value which is undefined.

Maybe you want to do this:

'use strict';

function Cat(name, age, breed) {
  this.name = name; this.age = age;
  if(breed || breed === 0)this.breed = breed;
}

Cat.prototype.breed = 'tabby';

var fluffy = new Cat('Fluffy the 3rd', '4 years');

console.log(fluffy);

Upvotes: 0

mrr
mrr

Reputation: 1243

Functions in Javascript do not require that you pass in the exact set of arguments that you define the function with. So this is fine:

function f() {
     console.log(arguments); // prints "1 2 3"
}

f(1, 2, 3);

And so is this:

function g(a, b, c) {
    console.log(a, b, c); // prints "undefined undefined undefined"
}
g();

If you pass more arguments than there are parameters (the first case), they are only accessible through the arguments array.

If you pass fewer arguments than there are parameters (the second case, and your case in your question), those parameters will be undefined inside the function.

That is why you get breed: undefined: when you call Cat, you aren't passing a breed, and unlike in most languages, Javascript has not given you an error, it has just bound the breed parameter to undefined.

Upvotes: 1

Related Questions