【JavaScript】手撕前端面试题:寄生组合式继承 | 发布订阅模式 | 观察者模式

这篇具有很好参考价值的文章主要介绍了【JavaScript】手撕前端面试题:寄生组合式继承 | 发布订阅模式 | 观察者模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🧑‍💼个人简介:大三学生,一个不甘平庸的平凡人🍬
🖥️ NodeJS专栏:Node.js从入门到精通
🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述)
🖥️ TypeScript知识总结:TypeScript从入门到精通(十万字超详细知识点总结)
👉 你的一键三连是我更新的最大动力❤️!


1、寄生组合式继承

要求

补全JavaScript代码,要求通过寄生组合式继承使"Chinese"构造函数继承于"Human"构造函数。要求如下:

  1. 给"Human"构造函数的原型上添加"getName"函数,该函数返回调用该函数对象的"name"属性
  2. 给"Chinese"构造函数的原型上添加"getAge"函数,该函数返回调用该函数对象的"age"属性

思路

寄生组合式继承是引用类型最理想的继承范式,它融合了组合式继承寄生式继承的优点,而组合式继承又是融合了原型链借用构造函数的技术,从而发挥两者之长,所以寄生组合式继承实际是三种技术的融合。

  • 寄生式继承的思路是:创建一个仅用于封装继承过程的函数
  • 组合式继承的思路是:使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。

这一题的思路是:

  1. 先创建一个inheritPrototype函数,该函数属于寄生式继承模式,作用是实现实现对原型属性和方法的继承:

    // subType子类构造函数,superType父类构造函数
    function inheritPrototype(subType,superType){
    	 // Object.create() 方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)。
         var prototype = Object.create(superType.prototype); // 创建父类型的一个副本对象
         prototype.constructor = subType; // 修复prototype的constructor 
         subType.prototype = prototype; // 将prototype设为subType的原型
     }
    

    这里涉及到原型链的知识:一个构造函数的prototype指向它的原型对象,而它的原型对象的constructor属性又指向到这个构造函数。上面的代码中因为要让prototype设置为subType的原型,所以prototype.constructor需要指向到subType

    调用inheritPrototype后,subType就继承了superType的属性和方法,这些属性和方法存在于subType的原型上,这样一来subType的所有实例就能访问到同一个存在的属性或方法(这些属性和方法相当于是公有的)。

  2. 给"Human"构造函数的原型上添加"getName"函数:

    Human.prototype.getName=function (){
       return this.name;
    }
    
  3. 通过借用构造函数来实现ChineseHuman实例属性的继承:

    function Chinese(name,age) {
    	// 继承了Human,还传了参数
        Human.call(this,name); // 借用构造函数模式
        this.age = age;
        this.color = 'yellow';
    }
    

    Chinese内部调用Human构造函数,实际上是为Chinese的实例设置了Human上具有的属性和方法(不包含Human原型上的属性和方法),这样一来Chinese的所有实例就能拥有自己的属性和方法(这些属性和方法相当于是私有的)。

  4. 调用inheritPrototype(Chinese,Human); 来实现ChineseHuman原型属性和方法的继承。

  5. 给"Chinese"构造函数的原型上添加"getAge"函数:

    Chinese.prototype.getAge=function(){
        return this.age;
    }
    

代码

function inheritPrototype(subType,superType) {
    var prototype = Object.create(superType.prototype);
    prototype.constructor = subType;
    subType.prototype = prototype;
}


function Human(name) {
    this.name = name
    this.kingdom = 'animal'
    this.color = ['yellow', 'white', 'brown', 'black']
}

Human.prototype.getName = function () {
    return this.name;
}

function Chinese(name,age) {
    Human.call(this,name);
    this.age = age;
    this.color = 'yellow';
}

inheritPrototype(Chinese,Human);


Chinese.prototype.getAge = function() {
    return this.age;
}

这题寄生组合式继承涉及到了JavaScript面向对象的程序设计,需要理解对象,构造函数,原型,原型链等的知识,博主之后会出文章对JavaScript面向对象的程序设计进行讲解,敬请期待!

2、发布订阅模式

要求

补全JavaScript代码,完成"EventEmitter"类实现发布订阅模式。

注意:文章来源地址https://www.toymoban.com/news/detail-402015.html

  1. 同一名称事件可能有多个不同的执行函数
  2. 通过"on"函数添加事件
  3. 通过"emit"函数触发事件

思路

  • 因为同一名称事件可能有多个不同的执行函数,所以我们需要先定义一个handler对象用来保存订阅事件的列表,对象内的key为订阅事件名称,value是一个包含该订阅事件所有的执行函数的数组
  • on函数接收两个参数,分别代表订阅事件名称和执行函数,在on函数内判断handler对象内是否存在该订阅事件,从而决定是向handler对象内初始化该订阅事件还是向该订阅事件的函数列表中添加新函数。
  • emit函数接收多个参数,第一个参数代表订阅事件名称,后面的参数是需要向订阅事件处理函数传递的参数,handler对象内存在该订阅事件时就遍历执行该订阅事件的函数列表数组中的所有处理函数。

代码

class EventEmitter {
    // 补全代码
    constructor() {
        this.handler = {}; // 保存订阅事件的列表
    }
    on(type, fn) {
        const fnArr = this.handler[type];
        if (fnArr) {
            // 如果订阅事件存在,存放订阅事件的回调函数
            fnArr.push(fn);
        } else {
            // 如果订阅事件不存在,则初始化该事件
            // 因为同一名称事件可能有多个不同的执行函数,所以用数组来存放所有的执行函数
            this.handler[type] = [fn];
        }
    }

    emit(type, ...args) {
        const fnArr = this.handler[type];
        if (fnArr) {
            // 如果订阅事件存在,遍历并执行订阅事件的处理函数
            fnArr.forEach(cb => cb(...args))
        }

    }
}

测试:

let sign1 = 0;
let sign2 = 0;
const emitter = new EventEmitter();
emitter.on('add', function () { sign1++ });
emitter.emit('add');
emitter.on('add', function () { sign2++ });
emitter.emit('add');
const judge = sign1 === 2 && sign2 === 1;
console.log(judge); // true

3、观察者模式

要求

补全JavaScript代码,完成"Observer"、"Observerd"类实现观察者模式

要求如下:

  1. 被观察者构造函数需要包含"name"属性和"state"属性且"state"初始值为"走路"。
  2. 被观察者创建"setObserver"函数用于保存观察者们。
  3. 被观察者创建"setState"函数用于设置该观察者"state"并且通知所有观察者。
  4. 观察者创建"update"函数用于被观察者进行消息通知,该函数需要打印(console.log)数据,数据格式为:小明正在走路。其中"小明"为被观察者的"name"属性,"走路"为被观察者的"state"属性。

注意:

  1. "Observer"为观察者,"Observerd"为被观察者。

思路

  • 根据题目的第二个要求:被观察者创建"setObserver"函数用于保存观察者们。可得知setObserver函数应该接受一个observer参数,该参数代表观察者,同时因为要保存这些观察则,所以在Observerd被观察者初始化的时候应该创建一个用来保存观察者的数组observers
  • 根据题目的第三个要求和第四个要求可知setState函数接受一个state参数用来更新Observerd被观察者自身的state,同时setState函数还应该遍历observers数组,并调用数组中的每一项的update方法,以此来通知所有观察者。

代码

// 被观察者
class Observerd {
    constructor(name) {
        this.name = name
        this.state = '走路'
        this.observers = [] // 存放观察者
    }
    setObserver(observer) {
        this.observers.push(observer)
    }
    setState(state) {
        this.state = state
        // 遍历通知每一个观察者
        this.observers.forEach(observer => {
            observer.update(this)
        })
    }
}
// 观察者
class Observer {
	// update被被观察者(Observerd)调用,用来接收被观察者的数据
    update(observerd) {
        console.log(observerd.name + '正在' + observerd.state);
    }
}

到了这里,关于【JavaScript】手撕前端面试题:寄生组合式继承 | 发布订阅模式 | 观察者模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 组合式(Composition)API

    组合式(Composition)API

    在vue中我们有两种API,一种是选项式,一种是组合式,其中选项式主要用于vue2,组合式主要用于vue3。 选项式API(Option API)  在vue2中我们书写选项式API,每个选项都有固定的书写位置,使用data选项来书写响应式数据,methods中书写方法。 优点: 写代码的位置已经约定好,结构

    2024年02月04日
    浏览(6)
  • vue3组合式笔记

    dfdf {{count}} {{state.count}} {{computedValue}} // // 校验 submit 事件 // submit: ({ email, password }) = { // if (email password) { // return true // } else { // console.warn(‘Invalid submit event payload!’) // return false // } // } // }) // function submitForm(email, password) { // emit(‘submit’, { email, password }) // } // input // type=“

    2024年02月06日
    浏览(8)
  • Java组合式异步编程CompletableFuture

    CompletableFuture是Java 8中引入的一个功能强大的Future实现类,它的字面翻译是“可完成的Future”。 CompletableFuture对并发编程进行了增强,可以方便地将多个有一定依赖关系的异步任务以流水线的方式组合在一起,大大简化多异步任务的开发。 CompletableFuture实现了两个接口,一个

    2024年04月09日
    浏览(7)
  • Vue3组合式API

    Vue3组合式API

    目录 composition API vs options API 体验 composition API setup 函数 reactive 函数 ref 函数 script setup 语法 计算属性 computed 函数 监听器 watch 函数 生命周期 模板中 ref 的使用 组件通讯 - 父传子 组件通讯 - 子传父 依赖注入 - provide 和 inject 保持响应式 - toRefs 函数 vue2 采用的就是 options API (

    2024年02月07日
    浏览(8)
  • 组合式升降压PFC的分析方法

    组合式升降压PFC的分析方法

      组合式升降压PFC采用两组储能元件,基本单元为Cuk,Sepic和Zeta。参考论文《New Efficient Bridgeless Cuk Rectifiers for PFC Applications》中的三种拓扑进行分析。   Cuk型PFC的TypeI如下图所示,正半周Dp一直导通,Vc1=Vac+Vo。其中Vac=Vacm sinwt,Vo=mVacm。此根据回路Vac,L1,C1,C2,L2可知,

    2023年04月17日
    浏览(8)
  • vue3组合式API介绍

    根据官方的说法,vue3.0的变化包括性能上的改进、更小的 bundle 体积、对 TypeScript 更好的支持、用于处理大规模用例的全新 API,全新的api指的就是本文主要要说的组合式api。 在 vue3 版本之前,我们复用组件(或者提取和重用多个组件之间的逻辑),通常有以下几种方式: M

    2023年04月22日
    浏览(7)
  • Vue3 组合式函数,实现minxins

    Vue3 组合式函数,实现minxins

    截至目前,组合式函数应该是在VUE 3应用程序中组织业务逻辑最佳的方法。它让我们可以把一些小块的通用逻辑进行抽离、复用,使我们的代码更易于编写、阅读和维护。 根据官方文档说明,在 Vue 应用的概念中, “组合式函数”是一个利用 Vue 组合式 API 来封装和复用有状态

    2024年02月08日
    浏览(7)
  • 快速入门vue3组合式API

    快速入门vue3组合式API

    (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹) 目录 使用create-vue创建项目 熟悉项目目录和关键文件  组合式API  setup选项 setup选项的写法和执行时机 script setup 语法糖 reactive和ref函数 reactive() ref() computed watch 侦听单个数据

    2024年02月12日
    浏览(8)
  • vue3组合式api单文件组件写法

    一,模板部分  二,js逻辑部分 

    2024年02月13日
    浏览(13)
  • vue3 组合式 api 单文件组件写法

    Vue3 中的 Composition API 是一种新的编写组件逻辑的方式,它提供了更好的代码组织、类型推导、测试支持和复用性。相比于 Vue2 的 Options API,Composition API 更加灵活和可扩展。 在 Composition API 中,我们使用 setup 函数来定义组件的逻辑部分。setup 函数是一个特殊的函数,在创建组

    2024年02月12日
    浏览(9)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包