如何使用Object.create()实现继承?解决继承属性undefined问题
解决Object.create()实现继承时属性undefined的问题
嘿,我来帮你理清这个问题!你的代码里rectangle.x返回undefined是因为对Object.create()的用法理解有点偏差,咱们一步步来修正。
错误原因分析
你写的var rectangle = Object.create(Shape)犯了一个关键错误:Object.create()的参数需要是原型对象,但你直接传入了构造函数Shape本身。Shape作为函数本身并没有x和y属性——这些属性是当你用new Shape()创建实例时,才会被添加到实例对象上的。所以你的rectangle对象的原型链指向的是Shape函数,自然找不到x和y。
解决方案1:直接继承Shape实例的属性
如果你只是想创建一个继承自Shape实例的对象,正确的做法是先创建一个Shape的实例,再把这个实例作为Object.create()的参数:
function Shape(){ this.x = 10; this.y = 20; } // 先创建拥有x、y属性的Shape实例 const shapeInstance = new Shape(); // 让rectangle的原型指向这个实例 const rectangle = Object.create(shapeInstance); console.log(rectangle.x); // 输出 10
这样rectangle就能通过原型链访问到shapeInstance上的x和y了。
解决方案2:实现构造函数的继承(更常用的场景)
如果你的需求是定义一个继承自Shape的子类(比如Rectangle),让子类实例既拥有Shape的实例属性,又能扩展自己的属性/方法,那我们需要结合Object.create()和调用父构造函数:
function Shape(){ this.x = 10; this.y = 20; } // 给Shape原型添加公共方法(可选) Shape.prototype.move = function(dx, dy) { this.x += dx; this.y += dy; }; // 定义子类Rectangle function Rectangle() { // 调用父构造函数,将当前子类实例作为this传入,继承x、y属性 Shape.call(this); // 添加子类专属属性 this.width = 50; this.height = 30; } // 让Rectangle的原型继承自Shape的原型,从而拿到原型上的方法(比如move) Rectangle.prototype = Object.create(Shape.prototype); // 修正constructor指向(否则Rectangle的constructor会指向Shape) Rectangle.prototype.constructor = Rectangle; // 添加子类专属方法 Rectangle.prototype.getArea = function() { return this.width * this.height; }; const rectangle = new Rectangle(); console.log(rectangle.x); // 10 rectangle.move(5,5); console.log(rectangle.y); // 25 console.log(rectangle.getArea()); // 1500
这种方式的优势在于:
- 通过
Shape.call(this)让子类实例拥有父类的实例属性 - 通过
Object.create(Shape.prototype)让子类继承父类原型上的公共方法 - 修正
constructor是为了保证原型链的正确性,避免后续类型判断出错
内容的提问来源于stack exchange,提问作者Prem
相关产品推荐
相关产品推荐

