Constructor property of objects created from a constructor function

Let’s say I have a constructor function:

function Bird(name) {
  this.name = name;
}

Now I create an object named duck.

let duck = new Bird("Donald");

Now the following quick commands and their outputs:

duck.constructor === Object; // returns false

According to this section of our module, this should return true.

I get this to be true only if I create object manually, i.e. without using any constructor:

let something = {};
something.constructor === Object; // returns true

This actually makes sense rather than duck.constructor === Object returning true since duck wasn’t created using the Object() constructor. Sure, it inherits features defined in Object.prototype, but the constructor isn’t the same.

This is clearly mentioned in MDN here:

Objects created without the explicit use of a constructor function (such as object- and array-literals) will have a constructor property that points to the Fundamental Object constructor type for that object.

Pardon me if I’ve missed something about the issue and posted in the wrong category. Thanks!

I’m no expert on this. but the way that I understand it is that Object is the constructor. So, that is the default constructor for any object you create. So, when I write this code:

function Bird(name) {
  this.name = name;
}

let duck = new Bird("Donald");
console.log('duck.constructor -->', duck.constructor);
console.log('duck.constructor === Object -->', duck.constructor === Object);

console.log('Object -->', Object);

let something = {};
console.log('something.constructor -->', something.constructor);
console.log('something.constructor === Object -->', something.constructor === Object);

I get this output:

duck.constructor --> ƒ Bird(name) {
  this.name = name;
}

duck.constructor === Object --> false

Object --> ƒ Object() { [native code] }

something.constructor --> ƒ Object() { [native code] }

something.constructor === Object --> true

So, it seems that Object and the default constructor are (presumably) the same thing. In the case of Bird, it got overwritten with your code.

And notice that if I log out Bird I get:

Bird --> ƒ Bird(name) {
  this.name = name;
}

This is identical to duck.contructor. So, both Bird and Object are constructors and they just get stored in the objects they construct.

Does that makes sense? Again, this isn’t my expertise, but this is how I read it.

If you like this kind of stuff, I recommend the YDKJS book series.

1 Like

Just to reiterate what @kevinSmith said:

With this:

duck.constructor === Bird; // false -- Oops
duck.constructor === Object; // true, all objects inherit from Object.prototype

The lesson means to prove you can have either or. So, without setting the constructor property:

Bird.prototype = {
  constructor: Bird, // define the constructor property
  numLegs: 2,

It is as the first code snippet mentions. However, after setting the constructor, this becomes what we want:

duck.constructor === Bird; // true-- Yay!
duck.constructor === Object; // false, cannot be both
1 Like

The point of the challenge (as far as I can tell) is to show that when you define the prototype, like it was done in the previous challenge, you overwrite the constructor. So you need to set it manually. I might just be repeating what was already said to be honest.

function Bird() {
  this.name = "Albert";
  this.color  = "blue";
  this.numLegs = 2;
}

let duck = new Bird('Jack')
console.log(duck.constructor === Object); // false
console.log(duck.constructor === Bird); // true

Bird.prototype = {
  numLegs: 2, 
  eat: function() {
    console.log("nom nom nom");
  },
  describe: function() {
    console.log("My name is " + this.name);
  }
};

duck = new Bird('Jack')
console.log(duck.constructor === Object); // true
console.log(duck.constructor === Bird); // false

Bird.prototype = {
  constructor: Bird,
  numLegs: 2, 
  eat: function() {
    console.log("nom nom nom");
  },
  describe: function() {
    console.log("My name is " + this.name);
  }
};

duck = new Bird('Jack')
console.log(duck.constructor === Object); // false
console.log(duck.constructor === Bird); // true
duck.constructor === Object

always returns false for any object created with constructor function, whether its constructor property is set or not.

Run this code to see what I mean:

function Dog(name) {
  this.name = name;
}

// Only change code below this line
Dog.prototype = {
  numLegs: 4,
  eat: function() {
    console.log("nom nom nom");
  },
  describe: function() {
    console.log("My name is " + this.name);
  }
};

const woof = new Dog("Woot");
console.log(woof.constructor === Object)
1 Like

So after setting an object’s prototype to an object it overwrites the constructor property to Object instead and so now woof.constructor === Bird is false but woof.constructor === Object is true. Am I stating that right?

This is how I interpret it:

So after setting an object’s constructor to an object it overwrites the constructor property to that object instead and so now woof.constructor === Dog is true but woof.constructor === Object is false.

That is, the default is variable.constructor === Object. Only once this is explicitly overwritten, does this not become true. However, this appears to only be precise for class objects (something declared with keyword class or inherit with prototypes.)

It is very case specific.

1 Like

I am a little bit confused with two different syntax of defining a constructor. In “Learn ES6”, we defined constructors using the “constructor” keyword. And now in this challenge, in OOP, we are defining constructors using the “function” keyword.
I already asked this question in FreeCodeCamp group on Facebook but I didn’t get what they said except that one can inherit and the other one can’t.

Can someone please explain this in simple terms but with all the details ?

function User (name) {
  this.name = name;
}

User.prototype.sayHello = function () {
  return `hello, my name is ${this.name}`;
}

Same thing:

class User {
  constructor (name) {
    this.name = name;
  }

  sayHello() {
    return `hello, my name is ${this.name}`;
  }
}

Like, literally the same, both are used the same way:

let user1 = new User("DanCouper");

The class syntax was added in 2015, it does exactly the same as the first example, but

  1. it’s arguably clearer,
  2. it visually encapsulates all the related functionality,
  3. it’s easier to understand for programmers coming to JS from other languages with classes,
  4. adds some safeguards to prevent common errors,
  5. allows inheriting from builtins, which I think it’s what someone had probably mentioned but isn’t very important (you can still normally use inheritance fine with the first example)
1 Like

Thank you for the clarification.
You defined it better than those Facebook guys.

1 Like