JavaScript高级 —— 学习(三)

目录

一、深入面向对象

(一)面向对象介绍

(二)面向对象编程 (oop)

1.面向对象编程介绍

2.面向对象编程优点

3.面向对象的特征

4.和面向过程编程对比

二、构造函数

(一)介绍

 (二)内存浪费

三、原型

(一)原型介绍

(二)constructor 属性

(三)对象原型

1.介绍

2.三者关系图

(四)原型继承

1.简单使用对象继承(有问题)

2.使用父构造函数继承

(五)原型链

1.原型链介绍

2.模型图讲解

3.原型链面试理解

练习:给数组拓展求最大最小值和求和方法

综合案例:模态框构造函数


一、深入面向对象

分为面向过程和面向对象两种,面向过程是以步骤来划分问题,在这儿不做过多描述。

(一)面向对象介绍

把事务分解成一个个对象,由对象之间分工合作,面向对象是以对象功能来划分问题,

(二)面向对象编程 (oop)

1.面向对象编程介绍

就是事情没有先后顺序,是并行进行的,每个对象都是功能中心,必须有明确分工。

2.面向对象编程优点

面向对象编程 灵活 容易维护和开发 适合多人合作大型软件项目

3.面向对象的特征

封装性

继承性

多态性

4.和面向过程编程对比

二、构造函数

(一)介绍

封装在面向对象编程中很重要,js 面向对象可以通过构造函数实现封装

构造函数体现了面向对象的封装特性

使用构造函数创建的对象彼此独立,互不影响

下面的 this 就是指向下面创建的对象 zhangsan

再创建一个别的指向就不同了 所以相互独立

<body><script>function Person(name, age){this.name = namethis.age = age }const zhangsan = new Person('张三', 18)console.log(zhangsan)</script>
</body>

 (二)内存浪费

构造函数 存在内存浪费的问题,张三和李四的吃饭方法都是相同的但是它们分别属于不同的对象,所以不相等,所以会浪费内存

<body><script>function Person(name, age){this.name = namethis.age = age this.eat = function(){console.log('我是人')}}const zhangsan = new Person('张三', 18)const lisi = new Person('李四', 20)console.log(zhangsan.eat === lisi.eat)</script>
</body>

三、原型

(一)原型介绍

用于解决构造函数内存浪费的问题,利用原型实现方法共享,原型分配的函数是所有对象共享的

每个构造函数都有一个 prototype 属性 原型在构造函数中,是一个对象,叫原型对象

这个对象可以挂载函数,对象实例化不会多次创建原型上函数节约内存

就是把公共的方法单独拿出来 使用 构造函数名.prototype.方法名 = ...   就不会多次创建浪费内存了

公共属性放构造函数里面就行

<body><script>function Person(name, age) {this.name = namethis.age = age}Person.prototype.eat = function () {console.log('吃吃吃')}const zhangsan = new Person('张三', 18)const lisi = new Person('李四', 20)console.log(zhangsan.eat === lisi.eat)</script>
</body>

原型对象中的 this 也指向 实例化后的对象 zhangsan,和构造函数中的 this 指向相同

<body><script>function Person(name, age) {this.name = namethis.age = age}Person.prototype.eat = function () {that = thisconsole.log('吃吃吃')}const zhangsan = new Person('张三', '18')zhangsan.eat()console.log(zhangsan === that)</script>
</body>

(二)constructor 属性

 每个原型对象都有 constructor 属性,这个属性指向原型对象 (prototype)的构造函数

如果有多个对象方法,可以给构造函数的原型对象赋值,来节省内存

原本 prototype 是一个对象 并通过 constructor 指向它的构造函数父亲 Person 但是经过给原型对象赋值后 覆盖了之前的 原型对象,之前能指向父亲的 constructor 属性消失了 所以就失去父亲了 这个原型对象就不知道是谁的儿子了

所以我们需要在赋值的大括号里面重新加上 constructor 属性 就能指向原来的父亲了就能正常调用里面的方法了

<body><script>function Person(name, age) {this.name = namethis.age = age}Person.prototype = {constructor: Person,sing: function () {console.log("唱歌")},dance: function () {console.log('跳舞')}}console.log(Person.prototype.constructor)</script>
</body>

(三)对象原型

1.介绍

构造函数中有原型对象,构造函数也能创建实例对象,正常来说,原型对象和实例对象是同等地位的,那么怎么实例对象可以调用原型对象中的方法呢?

当然是因为对象原型,对象都会有一个属性 __proto__ 指向构造函数的原型对象 prototype ,所以实例对象能调用原型对象中的方法(一边是两个下划线)

__proto__ 不是 js 标准写法 [[prototype]] 是一个意思表明 当前实例对象指向 某个原型对象

下面两个布尔值是相等的

<body><script>function Person(){}const zhangsan = new Person()console.log(zhangsan.__proto__ === Person.prototype)</script>
</body>
2.三者关系图

构造函数里本来就有 prototype 原型对象

构造函数能实例化实例对象

原型对象中有 constructor 属性指向 他的父亲构造函数

实例对象中 __proto__ 对象原型中的 constructor 属性也指向 父亲构造函数

实例对象的 对象原型 __proto__ 指向兄弟 原型对象 所以能调用其中的方法

 

(四)原型继承

1.简单使用对象继承(有问题)

如果有多个构造函数内部有很多相同的属性和方法,就可以再写一个对象把共同的部分单独提出来再用构造函数的原型对象继承

如下 男人女人 都具有人类的属性就把 人类属性单独提炼出来变成一个对象,然后前面学过如果是构造函数公用的部分,就得把相同的部分封装在原型对象中

所以把 Woman 和 Man 中的 prototype 用 Person 覆盖 这样就继承了Person的属性和方法,这样就能使用了,但是他俩都使用了Person 如果想要 添加各自单独的方法,就会污染 Person 对象

结果就是 在Woman 中创建的方法 在 Man 中 也能使用,因为他俩都继承了 Person ,都指向Person

<body><script>const Person = {eyes: 2,head: 1}function Woman() {}function Man() {}Woman.prototype = PersonWoman.prototype.contructor = WomanWoman.prototype.baby = function () {console.log('宝贝')}Man.prototype = PersonMan.prototype.contructor = Manconst zhangsan = new Woman()const lisi = new Man()console.log(lisi.baby())</script>
</body>
2.使用父构造函数继承

为了解决上面的问题,我们只要让每个构造函数的原型对象 被赋值的 Person 不一样就行了

就是

Man.prototype = Person1

Woman.prototype = Person2

就避免了上面的情况,因为现在 他俩指向的 Person 不同了,这样就不会互相影响了

思路就是把 数组 Person 也变成一个构造函数 然后每次 new Person() 都不一样就可以出现不一样的Person 对象了

改进代码如下:这样 lisi 就不具有 baby() 方法了

<body><script>function Person() {eyes = 2head = 1}function Woman() {}function Man() {}Woman.prototype = new Person()Woman.prototype.contructor = WomanWoman.prototype.baby = function () {console.log('宝贝')}Man.prototype = new Person()Man.prototype.contructor = Manconst zhangsan = new Woman()const lisi = new Man()console.log(zhangsan.baby())</script>
</body>

(五)原型链

1.原型链介绍

基于原型对象的继承使得不同构造函数的原型对象关联在一起,这种关系是一种链状的结构,将这种链状结构就成为原型链

只要是对象就有 __proto__,__proto__ 只指向原型对象 prototype

只要有原型对象就有 constructor,指向创建我的 构造函数

2.模型图讲解

__proto__ 就构成了原型链

基本的三角关系不过多描述了,前面有

实例对象 中有对象原型 __proto__ 指向 兄弟:父亲构造函数的原型对象 prototype

但是兄弟原型对象也是对象 也拥有对象原型 __proto__ 它指向的是更大的爷爷

就是 构造函数 Object 的原型对象 Object.prototype

Object.prototype 也能指向 Object 通过 Object.prototype.constructor 指向

但是原型对象 Object.prototype 也是对象也拥有对象原型 __proto__  但是没有更大的构造函数了,所以最后指向为 空 null 原型链就结束了

3.原型链面试理解

类似于作用域链

1.原型链就是一种查找规则,我们想要一些属性和方法,先看当前实例有没有当前方法

2.如果没有就查找它的原型 __proto__ 指向的 prototype 原型对象

3.如果还没有 就查找原型对象的原型

4.直到查到 null (Object)为止

__proto__ 原型对象为对象成员查找机制提供了一个方向/一条路路线

能用 instanceof 运算符检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

下面三个输出结果都是 true

Object 是最大的对象 数组也是对象 本质也是通过 const str = new Array() 出来的

<body><script>const str = [1,2,3]function Person(){}const zhangsan = new Person()console.log(str instanceof Array)console.log(zhangsan instanceof Person)console.log(zhangsan instanceof Object)</script>
</body>

练习:给数组拓展求最大最小值和求和方法

结果展示:

代码部分:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>const arr = [1, 2, 3]Array.prototype.max = function () {return Math.max(...this)}Array.prototype.min = function () {return Math.min(...this)}Array.prototype.sum = function () {return this.reduce((prev, item) => prev + item, 0)}console.log(arr.max())console.log(arr.min())console.log(arr.sum())</script>
</body></html>

综合案例:模态框构造函数

界面展示:

代码部分:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</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><script>function Modal(title = '', message = '') {this.box = document.createElement('div')this.box.className = 'modal'this.box.innerHTML = `<div class="header">${title}<i>×</i></div><div class="body">${message}</div>`}Modal.prototype.open = function () {const panduan = document.querySelector('.modal')panduan && panduan.remove()document.body.append(this.box)this.box.querySelector('i').addEventListener('click', () => {this.close()})}Modal.prototype.close = function () {this.box.remove()}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>

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

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

相关文章

【HTB】Trick 靶场

Trick靶场 地址&#xff1a;https://app.hackthebox.com/machines/477 打靶过程 靶机IP:10.129.227.180 1.信息收集 1.1 nmap 端口扫描 ┌──(root㉿kali)-[~/Desktop] └─# nmap -Pn -sC -sV -p- 10.129.227.180 --min-rate5000 Starting Nmap 7.94SVN ( https://nmap…

C++——list类及其模拟实现

前言&#xff1a;这篇文章我们继续进行C容器类的分享——list&#xff0c;也就是数据结构中的链表&#xff0c;而且是带头双向循环链表。 一.基本框架 namespace Mylist {template<class T>//定义节点struct ListNode{ListNode<T>* _next;ListNode<T>* _pre…

根据用户角色权限,渲染菜单的一个问题记录

个人博客&#xff1a;无奈何杨&#xff08;wnhyang&#xff09; 个人语雀&#xff1a;wnhyang 共享语雀&#xff1a;在线知识共享 Github&#xff1a;wnhyang - Overview 背景 之前一直讲过自己独立在做一个中后台管理系统&#xff0c;当然这个只是开始&#xff0c;未来会基…

Java复习第十四天学习笔记(CSS),附有道云笔记链接

【有道云笔记】十四 3.30 CSS https://note.youdao.com/s/3VormGXs 一、CSS定义和基本选择器 CSS定义&#xff1a;cascading style sheet 层叠样式表。 语法&#xff1a; 选择器 { 属性名1:属性值1; 属性名2:属性值2; 属性名3:属性值3; 属性名4:属性值4; } CSS使用&a…

实现顺序表(增、删、查、改)

引言&#xff1a;顺序表是数据结构中的一种形式&#xff0c;就是存储数据的一种结构。 这里会用到动态内存开辟&#xff0c;指针和结构体的知识 1.什么是数据结构 数据结构就是组织和存储数据的结构。 数据结构的特性&#xff1a; 物理结构&#xff1a;在内存中存储的数据是否连…

通过vite创建项目

一、VUE3官网 Vue.js - 渐进式 JavaScript 框架 | Vue.js (vuejs.org) 二、通过Vite创建项目 1、在cmd窗口下&#xff0c;全局安装vite //使用国内镜像源 npm config set registryhttps://registry.npmmirror.com//安装最新版vite npm install -g vitelatest Vite | 下一代…

Pygame基础11-mask 蒙版

蒙版 蒙版是二值化的图像&#xff0c;每个像素的值只能是0或1。 mask(蒙版)的用途&#xff1a; 碰撞检测部分着色 案例 和字母的碰撞检测 当玩家碰到字母 α \alpha α时&#xff0c;改变玩家颜色为绿色&#xff0c;否则为红色。 注意&#xff1a;我们希望碰到字母 α \alp…

考研数学1800还是660还是880?

24考完&#xff0c;大家都发现&#xff0c;没有一本习题册&#xff0c;覆盖了考试的所有知识点。 主流的模拟卷&#xff0c;都没有达到24卷的难度。 这就意味着&#xff1a; 一本习题册不够了&#xff01; 刷主流模拟卷不够了&#xff01; 这会需要整个考研复习的安排&…

C++(set和map详解,包含常用函数的分析)

set set是关联性容器 set的底层是在极端情况下都不会退化成单只的红黑树,也就是平衡树,本质是二叉搜索树. set的性质:set的key是不允许被修改的 使用set需要包含头文件 set<int> s;s.insert(1);s.insert(1);s.insert(1);s.insert(1);s.insert(2);s.insert(56);s.inser…

制造业工厂怎么通过MES系统来升级改造车间管理

在当今高度竞争的市场环境下&#xff0c;制造业企业需要不断提高生产效率&#xff0c;以在激烈的竞争中立于不败之地。而一种被广泛应用的方法就是利用MES控制系统&#xff0c;通过数字化管理和自动化控制来改造生产车间提升生产效率。 1、MES管理系统能够实现对生产过程的全面…

Navicat Premium 16 Mac/win---数据库设计、管理与维护轻松掌握数据库管理精髓

Navicat Premium是一款功能强大的数据库开发工具&#xff0c;支持多种数据库系统&#xff0c;如MySQL、Redis、MariaDB、Oracle等&#xff0c;并可与云数据库兼容&#xff0c;如Amazon RDS、Microsoft Azure等。它提供了直观易用的用户界面&#xff0c;使得开发者能够轻松上手并…

k8s calico由IPIP模式切换为BGP模式

按照官网calico.yaml部署后&#xff0c;默认是IPIP模式 查看route -n &#xff0c; 看到是tunl0口进行转发 怎么切换到BGP模式呢&#xff1f; kubectl edit ippool 将ipipMode由Always修改为Never &#xff0c;修改后保存文件即可。无需做任何操作&#xff0c;自动就切换为BG…

MySql实战--普通索引和唯一索引,应该怎么选择

在前面的基础篇文章中&#xff0c;我给你介绍过索引的基本概念&#xff0c;相信你已经了解了唯一索引和普通索引的区别。今天我们就继续来谈谈&#xff0c;在不同的业务场景下&#xff0c;应该选择普通索引&#xff0c;还是唯一索引&#xff1f; 假设你在维护一个市民系统&…

stm32cubeMX_io输入输出讲解

1创建项目&#xff08;可在专栏里找到&#xff09; 2进入当前页面点击引脚将弹出下图选项选择输入输出 带点击GPIO 点击引脚弹出如下选项根据需求选择 如有需要可以使用外部时钟&#xff1b;设置如图使用外部时钟 生成代码 将会弹出一个提示点击中间项//打开项目

HarmonyOS NEXT应用开发之MVVM模式

应用通过状态去渲染更新UI是程序设计中相对复杂&#xff0c;但又十分重要的&#xff0c;往往决定了应用程序的性能。程序的状态数据通常包含了数组、对象&#xff0c;或者是嵌套对象组合而成。在这些情况下&#xff0c;ArkUI采取MVVM Model View ViewModel模式&#xff0c;其…

clickhouse 源码编译部署

clickhouse 源码编译部署 版本 21.7.9.7 点击build project&#xff0c;编译工程&#xff0c;经过一定时间&#xff08;第一次编译可能几个小时&#xff0c;后续再编译&#xff0c;只编译有改动的文件&#xff09;生成release目录 在cmake-build-release → programs目录下…

vivado eFUSE 寄存器访问和编程

eFUSE 寄存器访问和编程 注释 &#xff1a; 在 MPSoC 和 Versal 器件上不支持以下 eFUSE 访问和编程方法。 7 系列、 UltraScale 和 UltraScale 器件具有一次性可编程位用于执行特定功能 &#xff0c; 称为 eFUSE 位。不同 eFUSE 位类型如 下所述&#xff1a; • …

单例(Singleton)设计模式

2.1 设计模式概述 设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索。就像是经典的棋谱&#xff0c;不同的棋局&#xff0c;我们用不同的棋谱。"套路" 经典的设计模式共有23种。每个…

语音识别:基于HMM

HMM语音识别的解码过程 从麦克风采集的输入音频波形被转换为固定尺寸的一组声学向量&#xff1a; 其中是维的语音特征向量&#xff08;例如MFCC&#xff09;。 解码器尝试去找到上述特征向量序列对应的单词&#xff08;word&#xff09;的序列&#xff1a; 单词序列的长度是。…

【大数据存储】实验4 NoSQL数据库

实验4 NoSQL数据库 NoSQL数据库的安装和使用实验环境&#xff1a; Ubuntu 22.04.3 Jdk 1.8.0_341 Hadoop 3.2.3 Hbase 2.4.17 Redis 6.0.6 mongdb 6.0.12 mogosh 2.1.0 Redis 安装redis完成 新建终端启动redisredis-server新建一个终端redis-cli 建表操作 尝…