关于使用Object.create()模拟经典继承的技术咨询
Hey there! Let's break down that Rectangle() constructor step by step since you already get the Shape part—great progress so far! 😊
First, let's pull up the full example code we're working with so we're on the same page:
// Parent constructor function Shape(x, y) { this.x = x; this.y = y; } // Parent prototype method Shape.prototype.move = function(x, y) { this.x += x; this.y += y; console.info('Shape moved.'); }; // Child constructor you're confused about function Rectangle(x, y, width, height) { Shape.call(this, x, y); this.width = width; this.height = height; } // Prototype inheritance setup Rectangle.prototype = Object.create(Shape.prototype); Rectangle.prototype.constructor = Rectangle; // Child prototype method Rectangle.prototype.area = function() { return this.width * this.height; };
1. Shape.call(this, x, y): Stealing the parent's instance properties
You already know the Shape constructor sets up x and y for shape instances. But here's the key: Object.create() only handles inheritance of prototype methods/properties—it doesn't automatically copy over the instance properties defined inside the parent constructor.
This call() method does one crucial thing: it binds the this keyword inside the Shape constructor to the new Rectangle instance we're creating. So when we run const myRect = new Rectangle(10, 20, 30, 40), call() makes sure the Shape constructor runs as if it's part of myRect, adding x:10 and y:20 directly to that Rectangle instance. No duplicate code, no extra objects—just clean inheritance of instance-level properties.
If we skipped this line, our Rectangle instances would have no x or y values, and calling myRect.move() would throw errors because this.x/this.y would be undefined.
2. this.width = width; this.height = height: Adding child-specific properties
This part is straightforward—we're adding properties that are unique to rectangles (width and height) that the generic Shape constructor doesn't need. Since these are specific to Rectangle instances, we initialize them directly in the child constructor.
new Shape(x, y) here You might wonder why we don't just do new Shape() inside the Rectangle constructor. The problem with that is it creates a separate Shape instance object, and the x/y properties would live on that object instead of our Rectangle instance. This leads to unnecessary nested objects and can cause weird behavior when accessing or modifying properties later. call() keeps everything clean on the single Rectangle instance.
Remember, full simulated classical inheritance needs two pieces:
Object.create(Shape.prototype)to let Rectangle instances access Shape's prototype methods (likemove())Shape.call(this, x, y)to inherit the instance properties from the parent constructor
That's the missing link you were looking for! Let me know if you want to dive deeper into any part of this.
内容的提问来源于stack exchange,提问作者DR01D

