JavaScript进阶--深入面向对象
深入面向对象
编程思想
-
面向过程:多个步骤=> 解决问题
性能较高,适合跟硬件联系很紧密的东西,如单片机
但代码维护成本高,扩展性差
-
面向对象:问题所需功能分解为一个一个的对象(分工合作)=> 接口
明确分工,灵活,代码可复用,容易维护和开发,适合大型软件项目
但性能较低
[!NOTE]
前端面向过程的代码较多
构造函数实现封装
==> 存在浪费内存问题【若属性,方法相同,则多存一个实例化对象,就会多浪费内存空间】
function Pig(name, age) {this.name = name;this.age = age;};const jogh = new Pig('jogh', 10);console.log(jogh.name);console.log(jogh.age);
原型对象 prototype
构造函数.prototype.方法名 = function(){...}
相当于构造函数中的一个属性
解决构造函数相同的成员造成的空间浪费
图解:
let that;function Pig(name, age) {this.name = name;this.age = age;that = this;console.log(that);};Pig.prototype.eat = function () {console.log("eat food");that = this;console.log(that);}const jogh = new Pig('jogh', 10);jogh.eat();
[!IMPORTANT]
构造函数和prototype的
this
都指向实例化对象
给数组扩展方法
通过原型prototype来拓展数组方法
//通过原型prototype来拓展数组方法//最大值Array.prototype.max = function () {return Math.max(...this);}//求和Array.prototype.sum = function () {return this.reduce((pre, cur) => pre + cur, 0);}//技巧:this就是指向实例对象的,所以不需要在把数组传进去方法中去//测试能否正常调用const arr1 = [1, 2, 3, 4, 5];const arr2 = [1, 5, 8, 3, 2];console.log(arr1.max());console.log(arr1.sum());console.log(arr2.max());console.log(arr2.sum());
constructor属性及其应用
==> 指向构造函数 【prototype中的一个属性】
应用
当对prototype
整体赋值时,会丢失指向构造函数的路径,需用constructor
来重新指向构造函数
function Pig(name, age) {this.name = name;this.age = age;};console.log(Pig.prototype);Pig.prototype = {sing: function () {console.log("sing");},dance: function () {console.log("dance");}};console.log(Pig.prototype);
图解
对象原型 __proto__
每个实例化对象都有的属性(只读)
==> 指向构造函数中的原型对象
注意
- JS非标准属性
[prototype]
和__proto__
意义相同- 也有
constructor
属性,指向构造函数
因为有了对象原型,实例化对象才可以直接调用原型对象中的方法
function Pig(name, age) {this.name = name;this.age = age;};console.log(Pig.prototype);const jogh = new Pig('jogh', 10);console.log(jogh.__proto__);console.log(jogh.__proto__.constructor);console.log(Pig.prototype.constructor);
图解:
原型继承
通过原型对象来继承一个实例化对象中的内容,本质是,创建一个需要被继承的实例化对象,然后原型对象保存了指向这个空间的地址,最后需要将constructor
重新指向对应的构造函数
//如果是通过一个实例化对象进行继承的话,如果继承的对象后续想给自己的原型对象中加点属性或方法,会导致所有的继承对象的原型对象都发生变化//原因:每个继承的对象的原型对象指向的是同一个实例化对象,也就是在栈中保存的是相同的地址//男人和女人function Man() {}//通过原型对象进行继承Man.prototype = new Person();//得重新指向构造函数Man.prototype.constructor = Man;Man.prototype.sing = function () {console.log("sing");}console.log(Man.prototype);console.log(new Man().__proto__.constructor);function Woman() {}//通过原型对象进行继承Woman.prototype = new Person();//得重新指向构造函数Woman.prototype.constructor = Woman;Woman.prototype.born = function () {console.log("baby");}console.log(Woman.prototype);console.log(new Woman().__proto__.constructor);
原型链
面试常考
由于原型对象的继承,使得不同构造函数的原型对象关联在一起 => 关系酷似链式解构,因此得名
[!IMPORTANT]
一种查找规则,当调用一个对象的成员时,先找自身==> 找不到则找自身的原型对象=>找不到则找自身原型对象的对象原型
一直找到Object.prototype为止
instanceof
判断某个实例化对象或者一个构造函数是否在Object的原型链上
function Person() {this.eyes = 2;}console.log(Person.prototype.__proto__ === Object.prototype);console.log(new Person().__proto__.__proto__ === Object.prototype);console.log(Person instanceof Object);console.log(Person instanceof Array);console.log([1, 2, 3] instanceof Array);console.log(Array instanceof Object);
综合案例
通过面向对象的方法实现提示框的功能
同个提示框的功能可以给其他按钮复用,只需更改参数
- 一个构造函数创建一个标签,多样化通过实参进行传入
- 在原型对象
prototype
上挂载open和closeclose
:在body中删除这个标签open
先判断是否已经由同类型标签,有则移除,添加对象到body中,绑定关闭事件
3.按钮点击:实例化=>调用open
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta http-equiv="X-UA-Compatible" content="IE=edge" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>面向对象封装消息提示</title><style>.modal {width: 300px;min-height: 100px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);border-radius: 4px;position: fixed;z-index: 999;left: 50%;top: 50%;transform: translate3d(-50%, -50%, 0);background-color: #fff;}.modal .header {line-height: 40px;padding: 0 10px;position: relative;font-size: 20px;}.modal .header i {font-style: normal;color: #999;position: absolute;right: 15px;top: -2px;cursor: pointer;}.modal .body {text-align: center;padding: 10px;}.modal .footer {display: flex;justify-content: flex-end;padding: 10px;}.modal .footer a {padding: 3px 8px;background: #ccc;text-decoration: none;color: #fff;border-radius: 2px;margin-right: 10px;font-size: 14px;}.modal .footer a.submit {background-color: #369;}</style>
</head><body><button id="delete">删除</button><button id="login">登录</button><!-- <div class="modal"><div class="header">温馨提示 <i>x</i></div><div class="body">您没有删除权限操作</div></div> --><script>//1.设置构造函数modal创建一个divfunction Modal(title = '', msg = '') {this.modal = document.createElement('div');this.modal.className = 'modal';this.modal.innerHTML = `<div class="header">${title} <i>x</i></div><div class="body">${msg}</div>`}//2.封装打开函数到prototype中Modal.prototype.open = function () {const box = document.querySelector('.modal')box && box.remove();document.querySelector('body').appendChild(this.modal);//绑定点击关闭事件this.modal.querySelector('i').addEventListener('click', () => {this.close();})}//3.封装关闭函数到prototype中Modal.prototype.close = function () {document.querySelector('body').removeChild(this.modal)}document.querySelector('#delete').addEventListener('click', () => {const del = new Modal('温馨提示', '您没有删除权限操作');del.open();})document.querySelector('#login').addEventListener('click', () => {const login = new Modal('友情提示', '您还没有登录欧');login.open();})</script>
</body></html>
相关文章:

JavaScript进阶--深入面向对象
深入面向对象 编程思想 面向过程:多个步骤> 解决问题 性能较高,适合跟硬件联系很紧密的东西,如单片机 但代码维护成本高,扩展性差 面向对象:问题所需功能分解为一个一个的对象(分工合作)>…...
Python列表专题:list与in
Python是一种强大的编程语言,其中列表(list)是最常用的数据结构之一。列表允许我们存储多个元素,并且可以方便地进行各种操作。在Python中,in运算符被广泛用于检测元素是否存在于列表中。本文将深入探讨Python列表及其与in运算符的结合使用。 1. Python列表的基础 1.1 什…...

利用Microsoft Entra Application Proxy在无公网IP条件下安全访问内网计算机
在现代混合办公环境中,如何让员工能够从任何地方安全访问公司内部资源成为了企业的重要挑战。传统的VPN解决方案虽然可以满足需求,但有时配置复杂,并可能涉及公网IP的问题。为了解决这个问题,Microsoft Entra(原Azure …...

【IEEE独立出版 | 厦门大学主办】第四届人工智能、机器人和通信国际会议(ICAIRC 2024)
【IEEE独立出版 | 厦门大学主办】 第四届人工智能、机器人和通信国际会议(ICAIRC 2024) 2024 4th International Conference on Artificial Intelligence, Robotics, and Communication 2024年12月27-29日 | 中国厦门 >>往届均已成功见刊检索…...
C++ 内存布局 - Part5: 继承关系中 构造析构与vptr的调整
这里以单继承为例,汇编采用AT&T格式,先看示例代码: #include <iostream>class Base { public:Base() {std::cout << "Base Constructor, this ptr: " << this << std::endl;printVptr();}virtual ~Ba…...
BUG-AttributeError: ‘EnforcedForest‘ object has no attribute ‘node‘
File “/home/adt/miniconda3/envs/bevdet/lib/python3.7/site-packages/trimesh/scene/transforms.py”, line 224, in nodes_geometry ‘geometry’ in self.transforms.node[n]): AttributeError: ‘EnforcedForest’ object has no attribute ‘node’ networkx 2.6.3 pyp…...
Spring Boot 3 配置 Redis 兼容单例和集群
配置项 Spring Boot 3.x 的 redis 配置和 Spring Boot 2.x 是不一样的, 路径多了一个data spring:...data:redis:host: redis.hostport: redis.portpassword: redis.passworddatabase: redis.database兼容单例和集群的配置 开发时一般用一个Redis单例就足够, 测试和生产环境…...
unsat钱包签名算法解析
unsat钱包签名算法解析 在数字货币领域,安全性是至关重要的,而签名算法则是确保交易和信息不可伪造的基础。本文将深入解析 unsat 钱包中使用的签名算法,重点关注如何生成和验证消息签名。 1. 签名算法概述 unsat 钱包使用 ECDSAÿ…...
mysql删除唯一索引
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...
学习之面试题:偏函数
偏函数(Partial Function)是 Python 中的一个实用工具,通常用于函数式编程中,可以固定一个函数的部分参数,从而生成一个新的函数。偏函数在 Python 中通常通过 functools.partial 实现。在面试中,考察偏函数…...

面试技术点
Java 一、jvm模块 jvm是什么? 是一用用于计算设备的规范,虚构出来的计算机,在计算机上仿真模拟各种计算机功能来实现 jvm 作用是什么? java中所有类必须装载jvm中才能运行,这个装载工作有jvm装载器完成,.class类型文件能在jvm虚拟器中运行,但不能直接在系统中运行,需要…...

基础sql
在执行删除操作之前,建议先运行一个 SELECT 查询来确认你要删除的记录。这可以帮助你避免误删数据。 删除字段id默认值为空字符串的所有数据 delete from users where id ; 删除字段id默认值为null的所有数据 delete from users where id is null; 删除字段upd…...

Jenkins整合Docker实现CICD自动化部署(若依项目)
前期准备 提前准备好jenkins环境 并且jenkins能使用docker命令,并且已经配置好了jdk、node、maven环境,我之前写了安装jenkins的博客,里面讲得比较详细,推荐用我这种方式安装 docker安装jenkins,并配置jdk、node和m…...
kali chrome 安装 hackbar
HackBar 是一个用于在 Kali Linux 中快速测试 SQL 注入和 XSS 漏洞的 Chrome 扩展程序。以下是如何在 Kali Linux 上安装 HackBar 的步骤: 首先,你需要确保你的系统已经安装了 Google Chrome 或 Chromium。如果没有安装,你可以使用以下命令安…...

一文了解 Linux 系统的文件权限管理
文章目录 引入Linux文件权限模型查看文件权限权限信息解析修改文件权限符号模式八进制数字模式 引入 在Linux操作系统中,我们想查看我们对文件拥有哪些权限时,可以在终端键入ls -l或ll命令,终端会输出当前路径下的文件信息,如文件…...

Spark:DataFrame介绍及使用
1. DataFrame详解 DataFrame是基于RDD进行封装的结构化数据类型,增加了schema元数据,最终DataFrame类型在计算时,还是转为rdd计算。DataFrame的结构化数据有Row(行数据)和schema元数据构成。 Row 类型 表示一行数据 …...

Linux系统:本机(物理主机)访问不了虚拟机中的apache服务问题的解决方案
学习目标: 提示:本文主要讲述-本机(物理主机)访问不了虚拟机中的apache服务情况下的解决方案 Linux系统:Ubuntu 23.04; 文中提到的“本机”:代表,宿主机,物理主机; 首先,…...

望繁信科技成功签约国显科技 流程挖掘助力制造业智造未来
近日,上海望繁信科技有限公司(简称“望繁信科技”)成功与深圳市国显科技有限公司(简称“国显科技”)达成合作。国显科技作为全球领先的TFT-LCD液晶显示及Mini/Micro LED显示产品供应商,致力于为笔记本、手机…...

枚举在Java体系中的作用
1. 枚举 枚举是在JDK1.5以后引入的。主要用途是:将一组常量组织起来,在这之前表示一组常量通常使用定义常量的方式: //用public static final修饰常量 public static final int RED 1; public static final int GREEN 2; public static f…...

『气泡水』Web官网 案例赏析
前言 Schweppes,作为一家享誉全球的气泡水品牌,致力于与年轻消费者建立更紧密的联系,并提升品牌影响力。为此,其打造了一个充满创意和高度互动性的官网,利用前端技术和动画效果,将产品特性与用户浏览体验完…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql
智慧工地管理云平台系统,智慧工地全套源码,java版智慧工地源码,支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求,提供“平台网络终端”的整体解决方案,提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...