0

I create a constructor for "car" and then create two cars, one using the "new" keyword, the other using "Object.create"

function car (name) {
    this.name=name
}

let car1 = new car("volvo")
let car2 = Object.create(car.prototype)
car2.name = "hyundai"

BTW: is it possible to set attributes immediately with "Object.prototype" like it is done with "new"? (so I wouldn't have to use the next line 'car2.name = "hyundai"')

If I then set a ".honk()" method to "car.prototype", it works for both "car1" and "car2":

car.prototype.honk= function (){
     return `${this.name}'s honk`
}

However, if I define the ".honk()" method within the "car" constructor, then "car1" is able to use it, but "car2" is not! Why?

function car (name) {
    this.name=name
    this.honk = function(){
        return `${this.name}'s honk`;
    }
}
Hrexandro
  • 11
  • 2
  • 3
    Because `Object.create` doesn’t invoke the constructor? – user3840170 Apr 25 '21 at 17:00
  • 1
    Because `Object.create` sets the prototype passed with the first argument, the second argument is purposed to pass the own properties of the new object. – Teemu Apr 25 '21 at 17:01

2 Answers2

0

You've just discovered the main difference between the new operator and Object.create. Both leverage prototypal inheritance, but only new makes use of the constructor, while Object.create just creates an object with the first parameter as prototype.

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • "*with no reference to the constructor*" is not quite true, the `.constructor` property of the received object points to the constructor :-) You could in fact write `const car2 = Object.create(car.prototype); car2.constructor("hyundai");` – Bergi Apr 25 '21 at 17:43
  • Right, thanks for pointing this out, I'm editing – Guerric P Apr 25 '21 at 17:45
0

is it possible to set attributes immediately with "Object.create" like it is done with "new"?

No, it is not. This is the entire point why we use constructors, to be able to initialise the properties of the new instances without repetitive code. Object.create, on the other hand, only creates an empty object that inherits from the give prototype.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Umm ... The second argument of [`Object.create`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#syntax) lets you to create own properties to the newly-created object, or did I somehow misunderstand the question? – Teemu Apr 25 '21 at 19:22
  • @Teemu I know, I ignored that to simplify (and, admittedly, because I've grown to dislike the second argument - `Object.create(…, …)` is the same as `Object.defineProperties(Object.create(…), …)`, which is clearer, and often `Object.assign(Object.create(…), …)` is easier). But regardless whether you use that, or `car2.name = "hyundai"` as the OP did, to initialise your properties - my main point was that it becomes repetitive once the initialisation code becomes more complex (such as creating own methods, like in the OP's last snippet). – Bergi Apr 25 '21 at 19:36
  • Setting own properties with `Object.create` is quite handy in some use-cases, maybe OP could benefit it later. I'd recall you blamed me years ago because I used an "overly complex" structure with properties object in an example fiddle. – Teemu Apr 25 '21 at 19:44