JavaScript继承 寄生组合式继承 extends

news2024/12/19 11:18:02

JavaScript继承

1、JS 的继承到底有多少种实现方式呢?
2、ES6 的 extends 关键字是用哪种继承方式实现的呢?
在这里插入图片描述

继承种类

原型链继承

function Parent1() {
    this.name = 'parentl'
    this.play = [1, 2, 3]
}

function Child1() {
    this.type = 'child2'
}

Child1.prototype = new Parent1();
console.log(new Child1());

let child1 = new Child1();
child1.play.push(4)
let child2 = new Child1();
console.log(child1.play,child2.play)

输出:

Parent1 { type: 'child2' }   
[ 1, 2, 3, 4 ] [ 1, 2, 3, 4 ]

特点
父类内存空间是共享的,当一个发生变化的时候,另外一个也随之进行了变化。

构造函数继承(借助 call)

function Parent1() {
    this.name = 'parent'
}

Parent1.prototype.getName = function () {
    return this.name;
}

function Child1() {
    Parent1.call(this);
    this.type = 'child1'
}

let child = new Child1();
console.log(child);
console.log(child.getName())

输出

Child1 { name: 'parent', type: 'child1' }
C:\Users\liyd\WebstormProjects\test\dataConvert.js:16                                  
console.log(child.getName())                                                           
                  ^                                                                    
                                                                                       
TypeError: child.getName is not a function    

缺点:
只能继承父类的实例属性和方法。不能继承原型属性和方法。

组合继承方式(推荐)

function Parent3() {
    this.name = 'parent3'
    this.play =[1,2,3]
}

Parent3.prototype.getName = function () {
    return this.name;
}

function Child3() {
    Parent3.call(this);
    this.type = 'child6'
}
// 第一次调用Parent3
Child3.prototype = new Parent3()
// 手动挂上构造器,指向自己的构造函数
Child3.prototype.constructor = Child3

var child3 = new Child3();
var child4 = new Child3();
child3.play.push(4)
console.log(child3.play,child4.play)
console.log(child3.getName())
console.log(child4.getName())

输出:

[ 1, 2, 3, 4 ] [ 1, 2, 3 ]
parent3                   
parent3   

原型式继承

let parent4 = {
    name:"parent4",
    friends:["p1","p2","p3"],
    getName:function () {
        return this.name
    }
}

let person4 = Object.create(parent4)
person4.name = "tom"
person4.friends.push("无始")

let person5 = Object.create(parent4);
person5.friends.push("狂蟒")

console.log(person4.name)
console.log(person4.name === person4.getName())
console.log(person5.name)
console.log(person4.friends)
console.log(person5.friends)

输出:

tom                                 
true                                
parent4                             
[ 'p1', 'p2', 'p3', '无始', '狂蟒' ]
[ 'p1', 'p2', 'p3', '无始', '狂蟒' ]

寄生式继承

使用原型式继承可以获得一份目标对象的浅拷贝然后利用这个浅拷贝的能力再进行增强添加一些方法

  • 寄生式继承相比于原型式继承还是在父类基础上添加了更多的方法
let parent5 = {
    name:"parent5",
    friends:["p1","p2","p3"],
    getName:function () {
        return this.name
    }
}

function clone(original) {
    let clone = Object.create(original)
    clone.getFriends = function (){
        return this.friends
    }
    return clone
}

let person5 = clone(parent5);
let person6 = clone(parent5);
person5.friends.push("666")
console.log(person5.getName())
console.log(person5.getFriends())
console.log(person6.getName())
console.log(person6.getFriends())

let person5 = clone(parent5);
console.log(person5.getName())
console.log(person5.getFriends())

输出:

parent5                    
[ 'p1', 'p2', 'p3', '666' ]
parent5                    
[ 'p1', 'p2', 'p3', '666' ]

寄生组合式继承(强烈推荐)

在前面这几种继承方式的优缺点基础上进行改造得出了寄生组合式的继承方式
这也是所有继承方式里面相对最优的继承方式

function clone(parent, child) {
    // 这里改用 Object.create 就可以减少组合继承中多进行一次构造的过程
    child.prototype = Object.create(parent.prototype)
    child.prototype.constructor = child
}

function Parent6(){
    this.name = "parent6"
    this.play = [1,2,3]
}

Parent6.prototype.getName = function () {
    return this.name
}

function Child(){
    Parent6.call(this)
    this.friends = 'child6'
}

clone(Parent6,Child)

Child.prototype.getFriends = function () {
    return this.friends
}


let person6 = new Child()
console.log(person6)
console.log(person6.getName())
console.log(person6.getFriends())

输出:

Child { name: 'parent6', play: [ 1, 2, 3 ], friends: 'child6' }
parent6                                                        
child6  

总结

在这里插入图片描述

extends 实现继承(超推荐 ES6)

语法糖

class Person{
    constructor(name) {
        this.name = name
    }

    getName = function () {
        console.log('Person:',this.name)
        return this.name
    }
}

class Gamer extends Person{
    constructor(name,age) {
        super(name);
        this.age = age
    }
}

let gamer = new Gamer("无始无终",26);
console.log(gamer.getName())

输出:

Person: 无始无终
无始无终 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1488073.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(十)SpringCloud系列——openfeign的高级特性实战内容介绍

前言 本节内容主要介绍一下SpringCloud组件中微服务调用组件openfeign的一些高级特性的用法以及一些常用的开发配置,如openfeign的超时控制配置、openfeign的重试机制配置、openfeign集成高级的http客户端、openfeign的请求与响应压缩功能,以及如何开启…

bashplotlib,一个有趣的 Python 数据可视化图形库

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站AI学习网站。 目录 前言 什么是Bashplotlib库? 安装Bashplotlib库 使用Bashplotlib库 Bashplotlib库的功能特性 1. 绘…

Linux速览(1)——基础指令篇

在上一章对Linux有了一些基础了解之后,本章我们来学习一下Linux系统下一些基本操作的常用的基础指令。 目录 1. ls 指令 2. pwd&&whoami命令 3. cd 指令 4. touch指令 5.mkdir指令(重要): 6.rmdir指令 && …

pandas行列求众数及按列去重

创建示例数据框如下: df2pd.DataFrame(data{A:[1,2,3,3,4,4,4,4],B:[a,b,c,c,d,d,d,d],C:[11,22,33,33,44,44,44,44],D:[11,22,33,33,44,44,44,44]}) print(df2.mode()) #求列众数 print(df2.loc[:,[A,C,D]].mode(axis1)) #求特定列的行众数 df2.drop_duplicates(s…

记一次:android学习笔记一(学习目录-不要看无内容)

学习目录如下 B站学习的名称--Android开发从入门到精通(项目案例版) 网址:https://www.bilibili.com/video/BV1jW411375J/ 第0章:安装 android stoid 参考地址https://blog.csdn.net/adminstate/article/details/130542368 第一章:第一个安卓应用 第二章:用户界面设…

类和对象基础知识

1. C和C语言最大的区别 以洗衣服为例, C语言是手洗,你需要对每一个过程非常的清楚,一步一步都需要自己亲自去完成, 而C更像是机洗,整个过程划分为人、衣服、洗衣粉、洗衣机四个对象的交互过程, 而人是不…

C语言指针的初步认识--学习笔记(2)

1.数组名的理解 我们在使⽤指针访问数组的内容时,有这样的代码: int arr[10]{1,2,3,4,5,6,7,8,9,10}; int* p&arr[0]; 这⾥我们使⽤ &arr[0] 的⽅式拿到了数组第⼀个元素的地址,但是其实数组名本来就是地址,⽽且 是数组…

React 事件机制原理

相关问题 React 合成事件与原生 DOM 事件的区别React 如何注册和触发事件React 事件如何解决浏览器兼容问题 回答关键点 React 的事件处理机制可以分为两个阶段:初始化渲染时在 root 节点上注册原生事件;原生事件触发时模拟捕获、目标和冒泡阶段派发合…

羊大师揭秘羊奶与健康,美味的保健佳品

羊大师揭秘羊奶与健康,美味的保健佳品 羊奶确实是一种美味且健康的保健佳品,其独特的营养成分和风味使其成为许多人的健康选择。以下是一些羊奶与健康的关系: 营养丰富:羊奶含有丰富的蛋白质、脂肪、矿物质和维生素,…

Go字符串实战操作大全!

目录 1. 引言文章结构概览 2. Go字符串基础字符串的定义与特性什么是字符串?Go字符串的不可变性原则 字符串的数据结构Go字符串的内部表达byte和rune的简介 3. 字符串操作与应用3.1 操作与应用字符串连接字符串切片字符串查找字符串比较字符串的替换字符串的大小写转…

【动态规划专栏】

动态规划基础知识 概念 动态规划(Dynamic Programming,DP):用来解决最优化问题的算法思想。 动态规划是分治思想的延伸,通俗一点来说就是大事化小,小事化无的艺术。 一般来说,…

Android 开发环境搭建的步骤

本文将为您详细讲解 Android 开发环境搭建的步骤。搭建 Android 开发环境需要准备一些软件和工具,以下是一些基础步骤: 1. 安装 Java Development Kit (JDK) 首先,您需要安装 Java Development Kit (JDK)。JDK 是 Android 开发的基础&#xf…

教师的调动谁有决定权

当你身边的老师突然“消失”,在另一所学校出现,你是否好奇过,这背后的调动是如何发生的?谁又是这场“迁徙”背后的决定者? 很多人可能首先想到的是校长。毕竟,在学校里,校长似乎是那个“发号施令…

前端从普通登录到单点登录(SSO)

随着前端登录场景的日益复杂化和技术思想的不断演进,前端在登录方面的知识结构变得越来越复杂。对于前端开发者来说,在日常工作中根据不同的登录场景提供合适的解决方案是我们的职责所在,本文将梳理前端登录的演变过程。 1、无状态的HTTP H…

【论文阅读】TensoRF: Tensorial Radiance Fields 张量辐射场

发表于ECCV2022. 论文地址:https://arxiv.org/abs/2203.09517 源码地址:https://github.com/apchenstu/TensoRF 项目地址:https://apchenstu.github.io/TensoRF/ 摘要 本文提出了TensoRF,一种建模和重建辐射场的新方法。不同于Ne…

面试题HTML+CSS+网络+浏览器篇

文章目录 Css预处理sass less是什么?为什么使用他们怎么转换 less 为 css?重绘和回流是什么http 是什么?有什么特点HTTP 协议和 HTTPS 区别什么是 CSRF 攻击HTML5 新增的内容有哪些Css3 新增的特性flex VS grid清除浮动的方式有哪些&#xff…

嵌入式入门必经之路:C语言学习计划

1、学习计划 学习基本语法和语言特性: 了解C语言的基本语法结构,如变量、数据类型、运算符等。学习控制流程语句,如条件语句、循环语句等。熟悉函数的定义和使用,包括参数传递和返回值。掌握C语言的输入输出操作,如pri…

力扣hot100:1.两数之和

输入中可能存在重复值 。 分析&#xff1a; 本题需要返回的是数组下标&#xff0c;因此如果需要使用排序然后双指针的话&#xff0c;需要用到哈希表&#xff0c;但是由于输入中可能存在重复值&#xff0c;因此哈希表的value值必须是vector<int>。 使用双指针求目标值targ…

lv20 QT事件5

1 事件模型 2 事件处理 virtual void keyPressEvent(QKeyEvent *event) virtual void keyReleaseEvent(QKeyEvent *event) virtual void mouseDoubleClickEvent(QMouseEvent *event) virtual void mouseMoveEvent(QMouseEvent *event) virtual void mousePressEvent(QMou…

打造专属投屏体验:Windows系统投屏到iOS系统

想要将电脑投屏共享给同事或朋友&#xff0c;又担心隐私内容泄露&#xff1f;来来来&#xff0c;这里有妙招&#xff01; AirDroid Cast网页版让电脑投屏变得挑剔&#xff0c;只展示你允许共享的内容。会议资料、个人照片、敏感文件&#xff0c;都将得到严格的筛选&#xff0c;…