当前位置: 首页 > news >正文

前端基础: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);});}}}

相关文章:

  • 4、设计模式之工厂模式
  • C语言常用的内存操作函数
  • 打豆豆game
  • 带你玩转OpenHarmony AI:打造智能语音子系统
  • SpringBoot基础详解
  • 指针变量加1为什么地址加了4?
  • Python01:初入Python(Mac)
  • 【计算机视觉(3)】
  • Docker 安装最新版MongoDB 限制内存 配置权限
  • 电影《朝云暮雨》观后感
  • SW 草图明显显示
  • C++---运算符重载
  • VUE3好看的酒网站模板源码
  • [猫头虎分享21天微信小程序基础入门教程]第13天:小程序的表单与用户输入处理
  • 9.6 Go语言入门(数组、切片和指针)
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • jquery ajax学习笔记
  • Sass Day-01
  • TCP拥塞控制
  • vue2.0项目引入element-ui
  • vuex 学习笔记 01
  • 将 Measurements 和 Units 应用到物理学
  • 面试总结JavaScript篇
  • 爬虫模拟登陆 SegmentFault
  • 小程序01:wepy框架整合iview webapp UI
  • - 语言经验 - 《c++的高性能内存管理库tcmalloc和jemalloc》
  • 主流的CSS水平和垂直居中技术大全
  • 从如何停掉 Promise 链说起
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • # linux从入门到精通(三)
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (10)STL算法之搜索(二) 二分查找
  • (27)4.8 习题课
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (笔记自用)LeetCode:快乐数
  • (二)换源+apt-get基础配置+搜狗拼音
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (三)c52学习之旅-点亮LED灯
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (转)负载均衡,回话保持,cookie
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • .net与java建立WebService再互相调用
  • .net中我喜欢的两种验证码
  • @Bean注解详解
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • [000-01-011].第2节:持久层方案的对比