手撕Js中的四种继承方式

简介: JavaScript本身也是一门面向对象的语言,面向对象的三大特点

JavaScript本身也是一门面向对象的语言,面向对象的三大特点

  1. 封装
  2. 继承
  3. 多态
  • 重写 子类重写父类的方法
  • 重载 相同的方法,由于参数或者返回值的不同,实现不同的作用

JavaScript中的重载有区别于其他语言,e.g.

function fn(x) {
  console.log(x)
}
function fn(x,y) {
  console.log(x,y)
}
fn(1,2) // 此时执行一定是第二个函数,没有完全重载的意义

今天说一下 JavaScript 中的继承,网上对继承有很多的文章了,但我总觉得很含糊,我认为Js中的继承,其实并不是严格意义上的继承,而是通过某种手段,达到继承的目的,也可以说是一种手法,网上各式各样的继承方法,其实都是使用这几种手法达成,下面进入正文:

正文

1. 基于原型的继承

不难看出来,这种方法其实就是利用原型&原型链的机制,将父类的实例对象或者原型对象,作为子类的原型,子类的实例可以访问子类的原型,也就是访问父类的对象或者原型对象,达到继承的目的。

function Parent() {
  this.x = 'parent x'
}
Parent.prototype.getX = function() {
  return this.x
}
Son.prototype = new Parent
Son.prototype.constructor = Son // 别忘了构造函数的原型上都有一个 constructor属性,实例对象上可没有
// 此处加入代码 Son.prototype = new Parent
// 此时
// son1.__proto__ === Son.prototype === new Parent「只是刚刚的那个实例对象,跟以后new出来的无关,接下来用 父实例1表示」
// Son.prototype.__proto__  === 父实例1.__proto__ === Parent.prototype
// 到这,你应该懂了,如果不懂,请去百度一下原型&原型链,搞明白再回来看看,记得收藏,留一条回来的路
function Son() {
  this.y = 'son y'
}
Son.prototype.getY = function() {
  return this.y
}
let son1 = new Son
// 没有加入 Son.prototype = new Parent
// son1.__proto__ === Son.prototype
// Son.prototype.__proto__ === Object.prototype
// 此处和 Parent构造函数没有半毛钱关系,无法使用Parent私有的或者公有的属性或者方法

这段代码可以实现子类对父类私有属性方法&原型属性方法的一个继承,原理很简单,就是原型&原型链的机制,但是他有弊端:


  1. 子类原型上的属性和方法必须在进行指向操作之后进行,不然的话会被父类的实例对象所覆盖
  2. 在父类的私有对象中添加属性和方法会添加到子类的原型上
  3. 此处重点记:父类中的私有属性方法变成了子类公有的。


2.基于 call 方法继承

个人感觉这个方法实现继承真的很糙,看代码吧

function Parent() {
  this.x = 'parent x'
}
Parent.prototype.getX = function() {
  return this.x
}
function Son() {
  Parent.call(this)
  // 你没看错,就上面这行代码,把函数Parent当做普通函数执行,把Parent的私有属性都走一遍,但是注意this,仅仅执行 Parent()的话,this指的是window,
  // 不要问为什么,不会的话去百度一下js的 this指向,搞明白再回来看看,记得收藏,留一条回来的路
  this.y = 'son y'
}
Son.prototype.getY = function() {
  return this.y
}
let son1 = new Son()

基于call方法去继承有一点点做 Copy的感觉,你觉得呢?弊端就是只能访问父类的私有属性,聪明的你应该知道下个方法是什么了(这俩组合到一块),这里我就不写了

3. 组合继承

emmmmmmmmmmmmmmm…

4.ES6福利继承(我瞎叫的)

class Parent {
  constructor() {
    this.x = 'parent x'
  }
}
class Son extends Parent {
  constructor() {
    super()
    // 这个super是必须得写的,其实它相当于父类的constructor执行,类似 call继承
    this.y = 'son y'
  }
}

个人觉得这四种继承模式是JavaScript中最基本的继承手段,网上好像有说8 || 9 种继承方法的,我没太细去看,感觉万变不离其宗吧应该。

目录
相关文章
|
2月前
|
JavaScript 前端开发
js开发:请解释原型继承和类继承的区别。
JavaScript中的原型继承和类继承用于共享对象属性和方法。原型继承通过原型链实现共享,节省内存,但不支持私有属性。
27 0
|
1月前
|
设计模式 JavaScript 前端开发
在JavaScript中,继承是一个重要的概念,它允许我们基于现有的类(或构造函数)创建新的类
【6月更文挑战第15天】JavaScript继承促进代码复用与扩展,创建类层次结构,但过深的继承链导致复杂性增加,紧密耦合增加维护成本,单继承限制灵活性,方法覆盖可能隐藏父类功能,且可能影响性能。设计时需谨慎权衡并考虑使用组合等替代方案。
35 7
|
1月前
|
JavaScript 前端开发
在 JavaScript 中,实现继承的方法有多种
【6月更文挑战第15天】JavaScript 继承常见方法包括:1) 原型链继承,利用原型查找,实例共享原型属性;2) 借用构造函数,避免共享,但方法不在原型上复用;3) 组合继承,结合两者优点,常用但有额外开销;4) ES6 的 class,语法糖,仍基于原型链,提供直观的面向对象编程。
25 7
|
26天前
|
设计模式 JavaScript 前端开发
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
JavaScript的继承机制基于原型链,它定义了对象属性和方法的查找规则。每个对象都有一个原型,通过原型链,对象能访问到构造函数原型上的方法。例如`Animal.prototype`上的`speak`方法可被`Animal`实例访问。原型链的尽头是`Object.prototype`,其`[[Prototype]]`为`null`。继承方式包括原型链继承(通过`Object.create`)、构造函数继承(使用`call`或`apply`)和组合继承(结合两者)。ES6的`class`语法是语法糖,但底层仍基于原型。继承选择应根据需求,理解原型链原理对JavaScript面向对象编程至关重要
33 7
【JavaScript】深入浅出JavaScript继承机制:解密原型、原型链与面向对象实战攻略
|
27天前
|
JavaScript 前端开发
JavaScript进阶-原型链与继承
【6月更文挑战第18天】JavaScript的原型链和继承是其面向对象编程的核心。每个对象都有一个指向原型的对象链,当查找属性时会沿着此链搜索。原型链可能导致污染、效率下降及构造函数与原型混淆的问题,应谨慎扩展原生原型、保持原型结构简洁并使用`Object.create`或ES6的`class`。继承方式包括原型链、构造函数、组合继承和ES6的Class继承,需避免循环引用、方法覆盖和不当的构造函数使用。通过代码示例展示了这两种继承形式,理解并有效利用这些机制能提升代码质量。
|
1月前
|
JavaScript 前端开发
JavaScript 继承的方式和优缺点
JavaScript 继承的方式和优缺点
|
21天前
|
JavaScript 前端开发
JavaScript 中,可以使用类继承来创建子类
JavaScript 中,可以使用类继承来创建子类
12 0
|
24天前
|
JavaScript 前端开发
JS的6种继承方式
JS的6种继承方式
15 0
|
1月前
|
JavaScript 前端开发
深入解析JavaScript中的面向对象编程,包括对象的基本概念、创建对象的方法、继承机制以及面向对象编程的优势
【6月更文挑战第12天】本文探讨JavaScript中的面向对象编程,解释了对象的基本概念,如属性和方法,以及基于原型的结构。介绍了创建对象的四种方法:字面量、构造函数、Object.create()和ES6的class关键字。还阐述了继承机制,包括原型链和ES6的class继承,并强调了面向对象编程的代码复用和模块化优势。
27 0
|
2月前
|
设计模式 JavaScript 前端开发
在JavaScript中,继承是一个重要的概念
【5月更文挑战第9天】JavaScript继承有优点和缺点。优点包括代码复用、扩展性和层次结构清晰。缺点涉及深继承导致的复杂性、紧耦合、单一继承限制、隐藏父类方法以及可能的性能问题。在使用时需谨慎,并考虑其他设计模式。
25 2