为何Object.create()设置后Shape.prototype与Rectangle.prototype不相等?
Shape.prototype === Rectangle.prototype结果为false? 咱们拆解代码里的每一步,就能把这个问题说透:
初始原型本就是独立对象
当你声明function Shape() {}和function Rectangle() {}时,JavaScript会自动为每个构造函数生成一个专属的原型对象。这时候Shape.prototype和Rectangle.prototype就是两个完全独立的对象,彼此没有任何关联,自然不可能相等。Object.create()生成了全新对象
执行Rectangle.prototype = Object.create(Shape.prototype)这行代码时,Object.create()的核心作用是:创建一个全新的空对象,并且把这个新对象的内部原型([[Prototype]])指向你传入的Shape.prototype。换句话说,你是把
Rectangle.prototype替换成了这个刚生成的新对象,而不是让它直接指向Shape.prototype本身。现在这两个变量指向的是内存里的两个不同对象:Shape.prototype是原本属于Shape构造函数的原型对象Rectangle.prototype是Object.create()刚造出来的新对象,只是它的原型链顶端连着Shape.prototype
===比较的是对象引用
JavaScript里用===比较对象时,判断的是两个变量是否指向内存中的同一个对象实例。既然Shape.prototype和Rectangle.prototype是两个完全不同的对象,比较结果必然是false。
你可以打印这两个对象直观感受一下:
console.log(Shape.prototype); // 输出: Shape {} console.log(Rectangle.prototype); // 输出: {} (这就是Object.create生成的新对象)
其实这么设计才是合理的:如果直接让Rectangle.prototype = Shape.prototype,那你给Rectangle.prototype添加方法时,会直接修改Shape.prototype,导致所有Shape的实例也会继承这些方法,这显然不是我们想要的继承效果。用Object.create()生成中间对象,既能让Rectangle继承Shape的原型方法,又能独立扩展自己的原型方法,不会影响到Shape的原型链。
内容的提问来源于stack exchange,提问作者Eric Yang

