js中两种设置子类原型(prototype)来实现原型式继承的本质区别

在JavaScript中,这两种设置子类(Child)原型(prototype)的方法虽然都能实现继承的基本功能,但它们之间存在一些重要的区别和潜在的陷阱。

1. Child.prototype = Object.create(Parent.prototype);

这个方法使用Object.create()来创建一个新对象,其原型(__proto__)被设置为Parent.prototype。这样做的结果是,Child.prototype会继承Parent.prototype上的所有属性和方法(注意,这里指的是原型链上的继承,而非实例属性或方法的继承),但不包括Parent构造函数内部可能初始化的任何实例属性或方法。

优点

  • 清晰地区分了原型链继承和构造函数实例初始化。
  • 避免了不必要的实例属性或方法被继承(即,只继承了原型上的属性和方法)。
  • 更符合原型链继承的初衷和原理。

示例

function Parent() {  
    this.name = 'Parent';  
}  
  
Parent.prototype.sayHello = function() {  
    console.log('Hello from Parent!');  
};  
  
function Child() {  
    this.age = 10;  
}  
  
Child.prototype = Object.create(Parent.prototype);  
Child.prototype.constructor = Child; // 需要手动修复constructor属性  
  
var child = new Child();  
console.log(child.sayHello()); // Hello from Parent!  
console.log(child.name); // undefined,因为name是Parent实例的属性,不是原型属性

下面通过代码解释一下 Object.create的实现流程

#详解 Object.create 实现逻辑
function create(proto) {
    function F(){}
    F.prototype = proto
    return new F()
}

 

2. Child.prototype = new Parent();

这个方法通过创建一个Parent的新实例,并将其赋值给Child.prototype。这会导致Child.prototype不仅继承了Parent.prototype上的所有属性和方法,还继承了Parent构造函数内部初始化的任何实例属性或方法(如果有的话)。

缺点

  • 如果Parent构造函数内部有对实例属性的初始化(如上例中的this.name = 'Parent';),这些实例属性也会被继承到Child.prototype上,这可能不是你想要的结果,因为原型上的属性或方法应该是被所有实例共享的,而不是每个实例都应该有自己的拷贝。
  • 可能导致不必要的内存消耗,因为每个通过Child构造函数创建的实例都会间接地包含一个Parent实例的所有实例属性(尽管它们通常不会被访问或使用)。

示例(注意,这里展示了潜在的问题):

function Parent() {  
    this.name = 'Parent'; // 这会被继承到Child.prototype上,通常不是期望的  
}  
  
Parent.prototype.sayHello = function() {  
    console.log('Hello from Parent!');  
};  
  
function Child() {  
    this.age = 10;  
}  
  
Child.prototype = new Parent(); // 这将'name'属性也带到了Child.prototype上  
Child.prototype.constructor = Child; // 需要手动修复constructor属性  
  
var child = new Child();  
console.log(child.sayHello()); // Hello from Parent!  
console.log(child.name); // 'Parent',这不是我们想要的,因为name应该是实例属性  
console.log(Child.prototype.name); // 'Parent',这证明了name被继承到了Child.prototype上

综上所述,Object.create(Parent.prototype)是更推荐的方式,因为它更清晰、更准确地实现了原型链继承,避免了不必要的实例属性被继承到原型上。

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨枫阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值