1

I probably did not make the title correctly but please someone explain why I can't create prototype for person object? Only works when I put hit to Object.prototype chain.

const person = {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

//person.prototype.hit = function(){
//    console.log("hitting me");
//}

Object.prototype.hit = function(){
    console.log("hitting me");
}

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();

(UPDATE) . Why does THIS work?? Not sure what the differences are actually from this example but this code works.

function person {
  isHuman: false,
  printIntroduction: function () {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
}();

person.prototype.hit = function(){

    console.log("hitting me");
}

/*
person.prototype.hit = function(){
    console.log("hitting me");
}
*/

Object.prototype.hit = function(){
    console.log("hitting me");
}

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();
// expected output: "My name is Matthew. Am I human? true"

update 2

Ok, so I make it work like below but clearly prototype doesn't work the way I expected.. so I am clearly confused about prototype

function person(){
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}

person.prototype.hit = function(){
    console.log("hitting me1");
}

Object.prototype.hit = function(){
    console.log("hitting me2");
}

const me = Object.create(person);

me.hit();

UPDATE 3.

thank you.. this is the explanation that I got from below.. thank you and this is clear now.

function person(){
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
}

person.prototype.hit = function(){
    console.log("hitting me1");
}

Object.prototype.hit = function(){
    console.log("hitting me2");
}

//const me = Object.create(person);
const me = new person;

me.hit();
user3502374
  • 781
  • 1
  • 4
  • 12

3 Answers3

2

If you would do this (quite similar to what you are doing):

 const person = {
   isHuman: false,
   printIntroduction: function () {
     console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
   },
   prototype: {
     hit(){ console.log("hutting me"); }
   }
 };

Then when you instantiate your object got a prototype property:

 const me = Object.create(person);
 me.prototype.hit();

The inheritance chain is:

 me -> person -> Object.prototype

And NOT:

 me -> person -> person.prototype -> Object.prototype

The prototype property actually hasnt to do much with inheritance, just imagine that it would not exist.


However it is important when talking about constructors. When you call a function with new in front, it is treated as a constructor, e.g.:

 var me = new Person()

And that is just syntactic sugar for:

 var me = Object.create(Person.prototype /*!!!*/);
 Person.call(me);

So when you set up a function, set its prototype property and call it with new, only then the prototype property of the constructor gets part of the instances prototype chain:

function Person(){}

Person.prototype.hit = () => console.log("works");

const me = new Person();
 me.hit();

Now the chain is:

me -> Person.prototype -> Object.prototype
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
2

Why can't I create prototype for person object?

Because person does not have a .prototype property, and doesn't need one.

The person object already has a prototype from which it inherits: Object.prototype (the default for all object literals). You shouldn't change that though.

Also, person does act as a prototype for the me object (i.e. me inherits from person). So if you want to give it another method, you should just write

person.hit = function(){
    console.log("hitting me");
};

that puts the hit function as a property of person in exactly the same way that printIntroduction is.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

Because JS is trying to access to a property called prototype rather than a "prototype" of that object.

To define a prototype, you need to use the function setPrototypeOf()

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  }
};

Object.setPrototypeOf(person, {
  'hit': function() {
    console.log("hitting me");
  }
});

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();

Or, you can declare that function directly into the object person

const person = {
  isHuman: false,
  printIntroduction: function() {
    console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
  },
  'hit': function() {
    console.log("hitting me");
  }
};

const me = Object.create(person);

me.name = "Matthew"; // "name" is a property set on "me", but not on "person"
me.isHuman = true; // inherited properties can be overwritten

me.printIntroduction();
me.hit();
Ele
  • 33,468
  • 7
  • 37
  • 75