如何在 JavaScript 中使用 __proto__ 实现对象的继承?

简介: 使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。

简单原型链继承

  • 原理:将子类的原型对象的__proto__指向父类的原型对象,从而使子类的实例能够继承父类原型上的属性和方法。
  • 示例
function Parent() {
   
  this.parentProperty = 'I am from Parent';
}
Parent.prototype.parentMethod = function() {
   
  console.log('This is parent method');
};

function Child() {
   }

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

const child = new Child();
console.log(child.parentProperty); 
// 输出:I am from Parent,通过原型链继承了父类的属性
child.parentMethod(); 
// 输出:This is parent method,通过原型链继承了父类的方法

在上述示例中,Object.create(Parent.prototype)创建了一个以Parent.prototype为原型的新对象,并将其赋值给Child.prototype,实现了简单的原型链继承。同时,需要手动将Child.prototype.constructor指向Child,以保证constructor属性的正确性。

借用构造函数继承属性与原型链继承方法相结合

  • 原理:通过在子类构造函数中使用callapply调用父类构造函数来继承父类的属性,再通过原型链继承父类的方法,这样既可以继承父类的属性,又可以避免子类实例共享父类实例的属性。
  • 示例
function Parent(name) {
   
  this.parentProperty = 'I am from Parent, my name is ' + name;
}
Parent.prototype.parentMethod = function() {
   
  console.log('This is parent method');
};

function Child(name) {
   
  Parent.call(this, name);
  this.childProperty = 'I am from Child';
}

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

const child = new Child('Bob');
console.log(child.parentProperty); 
// 输出:I am from Parent, my name is Bob,通过借用构造函数继承了父类的属性
console.log(child.childProperty); 
// 输出:I am from Child
child.parentMethod(); 
// 输出:This is parent method,通过原型链继承了父类的方法

在这个示例中,Parent.call(this, name)Child构造函数中调用了Parent构造函数,将父类的属性复制到了子类实例中。然后通过原型链继承了父类的方法,实现了更全面的继承方式。

寄生组合式继承

  • 原理:这是一种更优化的继承方式,它通过一个中间对象来继承父类的原型对象,避免了在子类原型上直接继承父类实例带来的一些问题,同时结合借用构造函数继承属性,实现了高效且更符合面向对象设计原则的继承。
  • 示例
function Parent(name) {
   
  this.parentProperty = 'I am from Parent, my name is ' + name;
}
Parent.prototype.parentMethod = function() {
   
  console.log('This is parent method');
};

function Child(name) {
   
  Parent.call(this, name);
  this.childProperty = 'I am from Child';
}

function inheritPrototype(child, parent) {
   
  const prototype = Object.create(parent.prototype);
  prototype.constructor = child;
  child.prototype = prototype;
}

inheritPrototype(Child, Parent);

const child = new Child('Bob');
console.log(child.parentProperty); 
// 输出:I am from Parent, my name is Bob
console.log(child.childProperty); 
// 输出:I am from Child
child.parentMethod(); 
// 输出:This is parent method

在寄生组合式继承中,inheritPrototype函数创建了一个中间对象来继承父类的原型对象,并正确设置了constructor属性,然后将子类的原型对象指向这个中间对象,实现了继承。这种方式在继承多个父类或需要更精细控制继承关系时非常有用,是一种较为推荐的继承方式。

使用__proto__实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用classextends关键字来实现更简洁和直观的继承语法,但理解基于__proto__的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。

相关文章
|
5天前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
10天前
|
JavaScript 前端开发
Javascript如何实现继承?
【10月更文挑战第24天】JavaScript 中实现继承的方式有很多种,每种方式都有其优缺点和适用场景。在实际开发中,我们需要根据具体的需求和情况选择合适的继承方式,以实现代码的复用和扩展。
|
4天前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
4天前
|
JavaScript 前端开发 开发者
js实现继承怎么实现
【10月更文挑战第26天】每种方式都有其优缺点和适用场景,开发者可以根据具体的需求和项目情况选择合适的继承方式来实现代码的复用和扩展。
17 1
|
5天前
|
JavaScript 前端开发 图形学
JavaScript 中 Math 对象常用方法
【10月更文挑战第29天】JavaScript中的Math对象提供了丰富多样的数学方法,涵盖了基本数学运算、幂运算、开方、随机数生成、极值获取以及三角函数等多个方面,为各种数学相关的计算和处理提供了强大的支持,是JavaScript编程中不可或缺的一部分。
|
28天前
|
缓存 JavaScript 前端开发
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
JavaScript中数组、对象等循环遍历的常用方法介绍(二)
29 1
|
29天前
|
存储 JavaScript 前端开发
js中函数、方法、对象的区别
js中函数、方法、对象的区别
15 2
|
24天前
|
JavaScript 前端开发 大数据
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
在JavaScript中,Object.assign()方法或展开语法(...)来合并对象,Object.freeze()方法来冻结对象,防止对象被修改
13 0
|
28天前
|
JavaScript 前端开发 索引
JavaScript中数组、对象等循环遍历的常用方法介绍(一)
JavaScript中数组、对象等循环遍历的常用方法介绍(一)
17 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
92 2