前端基础: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 Course
	if(!_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;
    }

    // LOL
    function 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;
    }

    // LOL
    function 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. 默认状态 - PENDING
            this.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. 默认状态 - PENDING
            this.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);
                });
            }
        }
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IP学习——ospf1

OSPF:开放式最短路径优先协议 无类别IGP协议:链路状态型。基于 LSA收敛,故更新量较大,为在中大型网络正常工作,需要进行结构化的部署---区域划分、ip地址规划 支持等开销负载均衡 组播更新 ---224.0.0.5 224.0.0.6 …

小程序properties默认值定义及父子组件的传值

因经常写vue,很久没写小程序,容易串频道,现记录一下小程序的组件用法、监听传入值及父子传值方式 首先小程序中传值是没有:(冒号)的,其次properties中定义默认值不需要写default 1.自定义组件中,首先json…

存储+调优:存储-IP-SAN

存储调优:存储-IP-SAN 数据一致性问题 硬盘(本地,远程同步rsync) 存储设备(网络) 网络存储 不同接口的磁盘 1.速率 2.支持连接更多设备 3.支持热拔插 存储设备什么互联 千…

iOS 17.5 release notes

文章目录 iOS 17.5 更新恢复了多年前删除的一些图片新增彩虹壁纸欧盟用户可直接从网站下载应用新增了追踪通知改进 Apple News图书应用"阅读目标"设计更新颜色匹配的播客小部件Web浏览器安全权限的访问下一代“Beats Pill”扬声器在iOS 17.5代码中得到确认店内Vision…

学硕都考11408的211院校!河北工业大学计算机考研考情分析!

河北工业大学(Hebei University of Technology),简称河北工大,坐落于天津市,由河北省人民政府、天津市人民政府与中华人民共和国教育部共建, 隶属于河北省,是国家“双一流”建设高校、国家“211…

企业微信主体机构如何修改?

企业微信变更主体有什么作用? 做过企业运营的小伙伴都知道,很多时候经常会遇到现有的企业需要注销,切换成新的企业进行经营的情况,但是原来企业申请的企业微信上面却积累了很多客户,肯定不能直接丢弃,所以这…

OpenAI宫斗剧番外篇: “Ilya与Altman联手对抗微软大帝,扫除黑恶势力”,“余华”和“莫言”犀利点评

事情是这样的。 小编我是一个重度的智谱清言用户,最近智谱清言悄悄上线了一个“划词引用”功能后,我仿佛打开了新世界的大门。我甚至用这个小功能,玩出来了即将为你上映的《OpenAI宫斗剧番外篇》。 3.5研究测试:hujiaoai.cn 4研…

Stable Diffusion vs Midjunery的区别和选择

现在网上最多的关于AI绘画的工具莫过于stable diffusion(sd)和midjunery(mj)了,最近尝试了一番,稍作总结吧算是。我们对于工具的使用通常考虑的无非就是好不好用,效果如何,当然还有费…

学习_C语言下使用ringbuffer实现任意数据类型的FIFO

思考及注意看:调试中的任意。 https://www.cnblogs.com/dreamboy2000/p/12982423.html

Mac虚拟机工具 CrossOver 24.0.0 Beta3 Mac中文版

CrossOver是一款在Mac上运行Windows应用程序的软件,无需安装虚拟机或重启计算机,简化了操作过程,提高了工作效率,为用户带来便捷体验。前往Mac青桔下载,享受前所未有的便利和高效。摘要由作者通过智能技术生成 CrossOv…

vulnhub靶场之FunBox-7

一.环境搭建 1.靶场描述 Boot2root in 6 steps for script-kiddies.Timeframe to root this box: 20 mins to never ever. Its on you.HINTS: Enum without sense, costs you too many time:Use "Daisys best friend" for information gathering. Visit "Karl…

使用决策树对金融贷款数据进行分析

使用决策树对金融贷款数据进行分析 在本篇博客中,我们将通过使用 Python、Pandas 和多种机器学习技术,对一组贷款数据进行全面分析。通过详细的步骤展示,你将学会如何进行数据预处理、可视化分析以及构建预测模型。 第一步:导入…

vscode添加代办相关插件,提高开发效率

这里写目录标题 前言插件添加添加TODO Highlight安装TODO Highlight在项目中自定义需要高亮显示的关键字 TODO Tree安装TODO Tree插件 单行注释快捷键 前言 在前端开发中,我们经常会遇到一些未完成、有问题或需要修复的部分,但又暂时未完成或未确定如何处…

专题汇编 | ChatGPT引领AIGC新浪潮(一)

ChatGPT的产生与迭代 2022年11月末,美国人工智能研究实验室OpenAI推出ChatGPT。上线的ChatGPT只用了2个月,活跃用户数就突破了1亿,创造了应用增速最快的纪录。 ChatGPT是什么 ChatGPT是一种人工智能技术驱动的自然语言处理(Natural Language Processing,NLP)工具,使用的…

多线程(八)

一、wait和notify 等待 通知 机制 和join的用途类似,多个线程之间随机调度,引入 wait notify 就是为了能够从应用层面上,干预到多个不同线程代码的执行顺序.( 这里说的干预,不是影响系统的线程调度策略 内核里的线程调度,仍然是无序的. 相当于是在应用程序…

RA-RISK ANALYSIS

文章目录 一、期刊简介二、征稿信息三、期刊表现四、投稿须知五、咨询 一、期刊简介 Risk Analysis代表风险分析学会出版,在ISI期刊引文报告中的社会科学、数学方法类别中排名前10位,为风险分析领域的新发展提供了焦点。这本国际同行评审期刊致力于发表…

VC++学习(3)——认识MFC框架,新建项目,添加按钮

目录 引出第三讲 MFC框架新建项目Windows搜索【包含内容的搜索】如何加按钮添加成员变量添加成功 添加按钮2杂项 总结 引出 VC学习(3)——认识MFC框架,新建项目,添加按钮 MFC(Microsoft Foundation Classes),是微软公…

基于springboot+vue的学生考勤管理系统

开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(九)

课程地址: 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程,一套精通鸿蒙应用开发 (本篇笔记对应课程第 16 节) P16《15.ArkUI-状态管理-任务统计案例》 1、实现任务进度卡片 怎么让进度条和进度展示文本堆叠展示&#xff1…

【UE5.1 多线程 异步】“Async Blueprints Extension”插件使用记录

目录 一、异步生成Actor示例 二、异步计算示例 参考视频 首先需要在商城中下载“Async Blueprints Extension”插件 一、异步生成Actor示例 2. 创建一个线程类,这里要指定父类为“LongAsyncTask”、“InfiniteAsyncTask”、“ShortAsyncTask”中的一个 在线程类…