前端基础:1-2 面向对象 + Promise

面向对象

对象是什么?为什么要面向对象?

通过代码抽象,进而藐视某个种类物体的方式

特点:逻辑上迁移更加灵活、代码复用性更高、高度的模块化
对象的理解
  • 对象是对于单个物体的简单抽象
  • 对象是容器,封装了属性 & 方法
    • 属性:对象状态
    • 方法:对象的能力 & 行为
//简单对象
const O = {name:'zhangsan',changeName: name => `新的${name}`
}
//函数对象
function O(){this.name = '张三'this.changeName = name => `新的${name}`
}

构造函数 - 生成对象 => 实例

  • 需要一个模板
  • 类即对象模板
  • js本质并不是基于类,而是基于构造函数(创建对象的特殊函数)+原型链
function Course() {this.name = 'zhangsan';this.changeName = name => `新的${name}`
}
const course = new Course(args);

Course本质就是构造函数

  • 函数体内使用的this,指向要生成的实例
  • 生成对象用new来实例化
  • 可以初始化传参
如果构造函数不初始化,可以使用具有相同功能吗? --无法具有
如果在项目中需要使用,且不希望外界感知的情况下,如何拿到实例后的对象? => 单例模式 (编写底层api代码时,尽量做到不让外部去感知区分内部类型)
function Course(){const _isClass = this instanceof Courseif(!_isClass){return new Course()}this.name = 'zhangsan'this.changeName = name => `新的${name}`
}
//使用
const course = Course()
思考:new是什么?/ new的原理? / new时候做了什么?
function Course(){}
const course = new Course()
  • 结构上:创建了一个空对象,作为返回的对象实例
  • 属性上:将生成空对象的原型对象指向了构造函数的prototype属性(course._ proto _=== Course.prototype)
  • 关系上:将当前对象实例赋给了内部的this
  • 生命周期上:执行了构造函数的初始化代码
function usernew(obj,...args){const newObj = Object.create(obj.prototype)const result = obj.apply(newObj,args)return typeof result === 'object' ? result : newObj
}
追问:实例属性影响 —— 独立的
function Course(teacher, leader) {this.teacher = teacher;this.leader = leader;
}
const course1 = new Course('张三', '王五'); // course1.leader => 王五
const course2 = new Course('李四', '赵六'); // course2.leader => 赵六
course2.teacher = 'xxxx'; // course1.teacher => 李四
constructor是什么?
 function Course(teacher, leader) {this.teacher = teacher;this.leader = leader;}const course = new Course('张三', '李四');
  • 每个对象在创建时,会自动拥有一个构造函数属性constructor

  • constructor源自原型对象,指向了构造函数的引用

  • 实例获得了模版的属性 => (大胆点)继承了类的属性

在这里插入图片描述

继承

js如何实现继承

在原型对象的所有属性方法,都可以被实例所共享
    function Game() {this.name = 'lol';}Game.prototype.getName = function() {return this.name;}// LOLfunction LOL() {};LOL.prototype = new Game();LOL.prototype.constructor = LOL;const game = new LOL();// 本质:重写了原型对象方式,将父对象的属性方法,作为自对象原型对象的属性方法,同时重写构造函数
追问:原型链直接继承有什么缺点
    function Game() {this.name = 'lol';this.skin = ['s'];}Game.prototype.getName = function() {return this.name;}// LOLfunction LOL() {};LOL.prototype = new Game();LOL.prototype.constructor = LOL;const game1 = new LOL();const game2 = new LOL();game1.skin.push('ss');// 本质:重写了原型对象方式,将父对象的属性方法,作为自对象原型对象的属性方法,同时重写构造函数
    1. 父类属性一旦赋值给到子类的原型属性,此时属性属于子类的共享属性了
    1. 实例化子类时,无法向父类进行传参

解决方法:构造函数继承

经典继承:在子类的构造函数内部调用父类的构造函数
    function Game(arg) {this.name = 'lol';this.skin = ['s'];}Game.prototype.getName = function() {return this.name;}function LOL(arg) {Game.call(this, arg);}const game3 = new LOL('arg');// 解决了共享属性问题 + 子向父传参的问题

追问:原型链上的共享方法无法被读取继承,如何解决?

组合继承
    function Game(arg) {this.name = 'lol';this.skin = ['s'];}Game.prototype.getName = function() {return this.name;}function LOL(arg) {Game.call(this, arg);}LOL.prototype = new Game();LOL.prototype.constructor = LOL;const game4 = new LOL('arg');

追问:组合继承方式就没有缺点吗? 问题在于:无论何种场景,都会调用两次父类的构造函数

解决方案:寄生组合继承
    function Game(arg) {this.name = 'lol';this.skin = ['s'];}Game.prototype.getName = function() {return this.name;}function LOL(arg) {Game.call(this, arg);}LOL.prototype = Object.create(Game.prototype);LOL.prototype.constructor = LOL;const game5 = new LOL('arg');

拔高:如何实现多重继承?

    function Game(arg) {this.name = 'lol';this.skin = ['s'];}Game.prototype.getName = function() {return this.name;}function Store() {this.shop = 'steam';}Game.prototype.getPlatform = function() {return this.shop;}function LOL(arg) {Game.call(this, arg);Store.call(this, arg);}LOL.prototype = Object.create(Game.prototype);Object.assign(Store.prototype,LOL.prototype);LOL.prototype.constructor = LOL;

浏览器原理

在这里插入图片描述

Promise - 可以处理回调地狱

    1. promise状态 - pending | fulfilled | rejected
      executor: new Promise的时候立即执行,接收两个参数 resolve | reject
    1. promise默认状态?状态是如何流转的? - 默认:pending 状态流转:pending => fufilled | pending => rejected
      内部维护成功value:undefined | thenable | promise
      内部维护失败变量reason
    1. promise返回值? - then方法:接收onFulfilled 和 onRejected
      如果then时,promise已经成功,执行onFulfilled,参数value
      如果then时,promise已经失败,执行onRejected,参数reson
      如果then中有异常,执行onRejected
Promise 方法
  1. Promise.all 全部执行完成
  2. Promise.race 有一个执行完成
手写promise
    const PENDING = 'PENDING';const FULFILLED = 'FULFILLED';const REJECTED = 'REJECTED';class Promise {constructor(executor) {// 1. 默认状态 - PENDINGthis.status = PENDING;// 2. 内部维护的变量值this.value = undefined;this.reason = undefined;// 成功的回调let resolve = value => {// 单向流转if (this.status === PENDING) {this.status = FULFILLED;this.value = value;}}// 失败的回调let reject = reason => {// 单向流转if (this.status === PENDING) {this.status = REJECTED;this.reason = reason;}}try {executor(resolve, reject);} catch (error) {reject(error);}}then(onFulfilled, onRejected) {if (this.status === FULFILLED) {onFulfilled(this.value);}if (this.status === REJECTED) {onRejected(this.reason);}}}// 追问:异步怎么办?const PENDING = 'PENDING';const FULFILLED = 'FULFILLED';const REJECTED = 'REJECTED';class Promise {constructor(executor) {// 1. 默认状态 - PENDINGthis.status = PENDING;// 2. 内部维护的变量值this.value = undefined;this.reason = undefined;// 存放回调this.onResolvedCallbacks = [];this.onRejectedCallbacks = [];// 成功的回调let resolve = value => {// 单向流转if (this.status === PENDING) {this.status = FULFILLED;this.value = value;this.onResolvedCallbacks.forEach(fn => fn());}}// 失败的回调let reject = reason => {// 单向流转if (this.status === PENDING) {this.status = REJECTED;this.reason = reason;this.onRejectedCallbacks.forEach(fn => fn());}}try {executor(resolve, reject);} catch (error) {reject(error);}}then(onFulfilled, onRejected) {if (this.status === FULFILLED) {onFulfilled(this.value);}if (this.status === REJECTED) {onRejected(this.reason);}if (this.status === PENDING) {// 存放队列this.onResolvedCallbacks.push(() => {onFulfilled(this.value);});this.onRejectedCallbacks.push(() => {onRejected(this.reason);});}}}

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

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

相关文章

Linux_应用篇(07) 系统信息与系统资源

在应用程序当中,有时往往需要去获取到一些系统相关的信息,譬如时间、日期、以及其它一些系统相关信息,本章将向大家介绍如何通过 Linux 系统调用或 C 库函数获取系统信息, 譬如获取系统时间、日期以及设置系统时间、日期等&#x…

三能一体运营体系助力政企支撑水平提升

生产力的发展是现代社会孜孜不倦的追求,由此产生了我们熟悉的“机械化、电子化、信息化”乃至现今正在发生的“智能化”四次工业革命。这些是由技术的突破性发展带来的,但我们也注意到生产力发展的另一个助力,即生产效率的提升,19…

【MySQL数据库】mysql日志管理、备份与恢复

mysql日志管理、备份与恢复 MySQL数据库备份及日志一、数据库备份分类:如何选择逻辑备份策略 (频率)完全备份与恢复备份恢复 增量备份与恢复实现增量备份 基于时间点与位置恢复 二.MySQL日志管理 MySQL数据库备份及日志 在生产环境中,数据的安全性是至关…

在未来你将何去何从?

在数字化的浪潮中,信息技术行业无疑是推动全球经济和社会发展的重要动力。随着科技的不断迭代与进步,云计算、大数据、人工智能(AI)、物联网(IoT)、5G通信和区块链等技术已经深入到我们生活的每一个角落&am…

鸿蒙原生应用元服务开发-鸿蒙真机运行项目实战与注意事项

一、解压项目注意项目包不能为中文 二、用数据线将装好DevEco Studio的电脑与设置为开发者模式的鸿蒙手机相连接。 三、将项目包托进DevEco Studio 中 注意项目包文件不能有嵌套 四、查看设备运行 五、点击项目结构 六、勾选红色框圈部分 登录开发者账号 七、选择好公司 八、等…

我是如何使用 Next.js14 + Tailwindcss 重构个人项目的

前言 去年在学习 React 和 Nest 的时候,参考了大佬 imsyy 的项目 DailyHot,以此项目的灵感基于 React 开发,完成之后就没怎么在意。 后来发现这个项目还有点小流量,每天差不多 200-400 的 IP 访问量: 我又抽时间优…

深度学习之基于Pytorch框架手写数字识别

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 手写数字识别是数字图像处理领域的一个经典问题,也是深度学习技术的一个常用应用场…

uniappx 获取设备唯一标识(OAID、AAID、AndroidID、IMEI等) Ba-IdCode-U

简介(下载地址) Ba-IdCode-U 是一款可以获取国内各大手机厂商 OAID(开放匿名设备标识)及海外手机平台 AAID(安卓广告标识)的uniapp插件。另外也支持获取 IMEI/MEID、AndroidID、WidevineID、PseudoID、GUI…

Spring Cloud Alibaba-06-Sleuth链路追踪

Lison <dreamlison163.com>, v1.0.0, 2024.4.03 Spring Cloud Alibaba-06-Sleuth链路追踪 文章目录 Spring Cloud Alibaba-06-Sleuth链路追踪为什么使用链路追踪常见链路追踪解决方案Sleuth概述概述Sleuth术语 Sleuth Zipkin 原理Sleuth原理简述Zipkin 原理简述 Sleut…

代码随想录——路径总和(Leetcode113)需要回顾

题目链接 递归 本题递归需要遍历整棵树&#xff0c;所以递归没有返回值 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* T…

苹果M4性能分析:进步神速?还有多少空间?

2024年初&#xff0c;苹果推出了M4处理器&#xff0c;令人意外的是&#xff0c;它的发布距离M3发布仅仅过去了半年时间。更让人惊讶的是&#xff0c;M4首次亮相于iPad Pro。这一新处理器不仅仅是M3的简单升级版本&#xff0c;而是一次全面的架构优化。本文将详细分析M4处理器的…

Vue基础(1)数据绑定

一. 文本插值 普通文本可以使用双大括号 {{ }} &#xff0c;要想插入 HTML&#xff0c;需要使用 v-html 指令。 <template><h1>Message: {{ state.msg }}</h1><p>{{ state.count 1 }}</p><p>{{ state.rawHtml }}</p><p v-html…

【教学类-58-02】黑白三角拼图02(3*3宫格)262144种

背景需求&#xff1a; 已知黑白三角拼图2*2&#xff08;4个拼图&#xff09;一共有256种排列方法 【教学类-58-01】黑白三角拼图01&#xff08;2*2宫格&#xff09;256种-CSDN博客文章浏览阅读142次&#xff0c;点赞5次&#xff0c;收藏12次。【教学类-58-01】黑白三角拼图01…

深度学习之基于Matlab卷积神经网络(CNN)手写数字识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 手写数字识别是计算机视觉领域的一个重要问题&#xff0c;也是深度学习应用的一个典型场景。卷…

什么是固态继电器?

固态继电器是不需要使用任何机械部件的开关继电器。这通常使它们具有比普通机电继电器寿命更长的优势&#xff0c;然而&#xff0c;尽管固态继电器速度快且耐用&#xff0c;但仍具有某些设计规定。 固态继电器风靡全球&#xff0c;彻底改变了从农业自动化到航空航天等各个行业…

银行总部文件自动下发,如何保证不影响专线网络使用?

银行在我国金融体系中占据重要地位&#xff0c;是我国市场经济的重要组成部分。我国商业银行随着自身不断发展&#xff0c;规模日益扩大&#xff0c;形成了“总行-分行-支行-营业网点”的典型层级管理模式。在日常中&#xff0c;银行总部存在文件下发的场景&#xff1a; 银行总…

多家知名媒体到访“光子1号金融算力中心“ 交流AI与算力未来观

5月23日&#xff0c;企商在线 “光子1号金融算力中心媒体参观日”活动成功举办&#xff0c;十多家主流媒体、IT行业媒体及自媒体代表走进光子1号金融算力中心&#xff0c;深入了解企商业务发展、战略规划及“光子1号金融算力中心”等企商打造的新型数字基础设施&#xff0c;共同…

Python条件分支与循环

大家好&#xff0c;当涉及到编写高效和灵活的程序时&#xff0c;条件分支和循环是 Python 中至关重要的概念。它们允许我们根据不同的条件执行不同的代码块&#xff0c;或者重复执行一组语句。条件分支和循环是测试开发工程师在日常工作中经常使用的工具&#xff0c;无论是编写…

光耦合器的特性和应用概述

光耦合器又称光电耦合器&#xff0c;是现代电子学中必不可少的元件&#xff0c;确保隔离电路之间安全有效的信号传输。本文探讨了光耦合器的特性及其多样化应用&#xff0c;强调了它们在各种电子系统中的关键作用。 什么是光耦合器&#xff1f; 光耦合器是一种设计用于利用光传…

【MySQL数据库】CRUD 增 删 改 查 超详解,有这一篇就够了!

​ ​ &#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【MySQL】探秘&#xff1a;数据库世界的瑞士军刀 目录 ⚗️一.CRUD &#x1f9ea;二.新增&#xff08;Create&#xff09; &#x1f9eb;1.基本操作 &#x1f9ec;2.使用SELECT插入 &#x…