Joe.wang
Joe.wang

Reputation: 11793

Understand Object.create

After reading the Object.create document. I did some test for it . Here is my code . please review it.

function Shape() {
  this.x = 0;
  this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

Rectangle=Object.create(Shape);

Rectangle.move(); //?? why move function is not found ?

As the document says Object.create(proto[,propertiesObject]); proto should be the prototype of the newly-created object. So, Rectangle.prototype should be equal with the Shape. but actually it is not. Apparently I didn't understand this part of document. and I still found Rectangle.__proto__==Shape is true. OK, Even Rectangle.__proto__==Shape is true , Why Rectangle can't find the move function? Is the move function not in the prototype chain?? I thought the move function is in the Rectangle.__proto__.prototype, It supposed to be found in the chain. Why can not? thanks.

Upvotes: -1

Views: 139

Answers (2)

Entity Black
Entity Black

Reputation: 3491

maybe this will help you to understand a little bit more:

https://www.youtube.com/watch?v=DwYPG6vreJg&feature=player_detailpage#t=739s

Here he explains that it doesn't work same as you said. Your argument that

I thought the move function is in the Rectangle.__proto__.prototype

is correct. You can find move as Rectangle.__proto__.prototype.move but it doesn't implies that you can find it as Rectangle.move. Prototype chain is interrupted. I think that it is detaily described in the video.

Try to think about these parts of code:

function Shape() {
    this.x = 0;
    this.y = 0;
}

Shape.__proto__.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

Rectangle=Object.create(Shape);

Rectangle.move();

or:

function Shape() {
    this.x = 0;
    this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

Rectangle=Object.create(Shape);

Rectangle.prototype.move();

(x and y are still incorrect in these cases, but you weren't asking about them ;) )

Upvotes: 2

Qantas 94 Heavy
Qantas 94 Heavy

Reputation: 16020

The prototype must be an actual object. In this case, you should pass Shape's prototype, not the Shape function.

function Shape() {
  this.x = 0;
  this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

Rectangle=Object.create(Shape.prototype, {a:1});

Rectangle.move(); // it will call now
Rectangle.a; // 1
Rectangle.x; // NaN ???
Rectangle.y; // NaN ???

Note that Object.create() is not the same as using the new keyword - that might be what you were looking for instead.

function Shape() {
  this.x = 0;
  this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

Rectangle=new Shape;

Rectangle.move(1,2); // works properly now
Rectangle.a; // undefined, we never made one
Rectangle.x; // 1
Rectangle.y; // 2

As Javascript actually looks up the constructor and its .prototype to find the prototype recursively, it won't look up Shape's prototype as it was not directly set nor was the new constructor used to create Rectangle:

function Shape() {
  this.x = 0;
  this.y = 0;
}

Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info("Shape moved.");
};

Rectangle = Object.create(Shape);
Rectangle.constructor; // Function()
Rectangle.constructor.prototype; // That's Function.prototype
/* as you can see Shape.prototype is never touched by the prototype chain */

Rectangle.__proto__; // Shape(), not the prototype (doesn't have any direct properties on it)

Rectangle.move(1,2); // TypeError: Rectangle.move is not a function
Rectangle.a; // does not exist
Rectangle.x; // function never called on Rectangle, so also doesn't exist
Rectangle.y; // function never called on Rectangle, so also doesn't exist

Upvotes: 3

Related Questions