js面试题,函数封装问题。

节流子 2021-05-14 12:11:37
有人知道这个怎么封装吗?我大概思路是创建一个函数,然后根据传入参数不同做判断,返回不同结果,但写的时候发现不知道怎么写,很尴尬,不会封装
...全文
226 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
节流子 2021-05-14
  • 打赏
  • 举报
回复
引用 4 楼 泡泡鱼_的回复:
搞反了吧,楼主要求是要封装成对外统一调用的。 [quote=引用 1 楼 我爱小仙女 的回复:]

class Player {
  constructor (nodeId, videoId) {
    this.nodeId = nodeId
    this.videoId = videoId
  }

  play () {
    console.log('play...', this.nodeId, this.videoId)
  }

  pause () {
    console.log('pause...', this.nodeId, this.videoId)
  }
}

class TxPlayer extends Player {
  constructor (options) {
    super(options.containerId, options.vid)
  }

  play () {
    super.play()
  }

  pause () {
    super.pause()
  }
}

class EgamePlayer extends Player {
  constructor (options) {
    super(options.domId, options.videoId)
  }

  start () {
    super.play()
  }
  stop () {
    super.pause()
  }
}
[/quote] 我还没试效果,还要敲一下看看
泡泡鱼_ 2021-05-14
  • 打赏
  • 举报
回复
搞反了吧,楼主要求是要封装成对外统一调用的。
引用 1 楼 我爱小仙女 的回复:

class Player {
  constructor (nodeId, videoId) {
    this.nodeId = nodeId
    this.videoId = videoId
  }

  play () {
    console.log('play...', this.nodeId, this.videoId)
  }

  pause () {
    console.log('pause...', this.nodeId, this.videoId)
  }
}

class TxPlayer extends Player {
  constructor (options) {
    super(options.containerId, options.vid)
  }

  play () {
    super.play()
  }

  pause () {
    super.pause()
  }
}

class EgamePlayer extends Player {
  constructor (options) {
    super(options.domId, options.videoId)
  }

  start () {
    super.play()
  }
  stop () {
    super.pause()
  }
}
节流子 2021-05-14
  • 打赏
  • 举报
回复
引用 2 楼 我爱小仙女的回复:
封装的时候,针对不同入参,最好要有一个中间层,不要根据传入参数不同做判断 如果做判断的话,后续假如再让你加一个 AQYPlayer,你还要追加参数判断,这样改业务代码是不提倡的
谢谢,晚上还在看js函数封装的视频,发现还是不会
我爱小仙女 2021-05-14
  • 打赏
  • 举报
回复
封装的时候,针对不同入参,最好要有一个中间层,不要根据传入参数不同做判断 如果做判断的话,后续假如再让你加一个 AQYPlayer,你还要追加参数判断,这样改业务代码是不提倡的
我爱小仙女 2021-05-14
  • 打赏
  • 举报
回复

class Player {
  constructor (nodeId, videoId) {
    this.nodeId = nodeId
    this.videoId = videoId
  }

  play () {
    console.log('play...', this.nodeId, this.videoId)
  }

  pause () {
    console.log('pause...', this.nodeId, this.videoId)
  }
}

class TxPlayer extends Player {
  constructor (options) {
    super(options.containerId, options.vid)
  }

  play () {
    super.play()
  }

  pause () {
    super.pause()
  }
}

class EgamePlayer extends Player {
  constructor (options) {
    super(options.domId, options.videoId)
  }

  start () {
    super.play()
  }
  stop () {
    super.pause()
  }
}
泡泡鱼_ 2021-05-14
  • 打赏
  • 举报
回复
TxPlayer播放器和EgamePlayer播放器


/**
 * @description `TxPlayer播放器`
 */
class ITxPlayer implements IPlayer {
    /** `TxPlayer的实例化对象` */
    private player;
    /**
     * 构造器
     * @param {Record<string, any>} options 配置
     */
    constructor (options: Record<string, any>) {
        this.player = new TxPlayer(options)
    }

    play (): void {
        this.player.play()
        console.log('TXPlayer play')
    }

    pause (): void {
        this.player.pause()
        console.log('TXPlayer pause')
    }
}

/**
 * @description `EgamePlayer播放器`
 */
class IEgamePlayer implements IPlayer {
    /** `EgamePlayer的实例化对象` */
    private player;
    /**
     * 构造器
     * @param {Record<string, any>} options 配置
     */
    constructor (options: Record<string, any>) {
        this.player = new EgamePlayer(options)
    }

    play (): void {
        this.player.start()
        console.log('EgamePlayer play')
    }

    pause (): void {
        this.player.stop()
        console.log('EgamePlayer pause')
    }
}

对外统一的播放器类Player

/**
 * @description `统一的播放器类Player`
 */
class Player implements IPlayer {
    /** `对应播放器实例化对象` */
    private player: IPlayer;
    /**
     * 构造器
     * @param {number} mode 类型
     * @param {Record<string, any>} options 配置
     */
    constructor (mode: number, options: Record<string, any>) {
        // 这里只是简单的用mode参数来代表“不同的视频类型”
        this.getInstance(mode, options)
    }

    /**
     * @description `根据类型获取播放器实例`
     * @param {number} mode 类型
     * @param {Record<string, any>} options 配置
     */
    private getInstance (mode: number, options: Record<string, any>) {
        switch (mode) {
            case 1:
                this.player = new ITxPlayer(options)
                break
            case 2:
                this.player = new IEgamePlayer(options)
                break
            default:
                this.player = new ITxPlayer(options)
                break
        }
    }

    play (): void {
        this.player.play()
    }

    pause (): void {
        this.player.pause()
    }
}
export default Player
泡泡鱼_ 2021-05-14
  • 打赏
  • 举报
回复
引用 8 楼 ziqi0716 的回复:
抽象出播放器接口,包含播放与停止两个函数。 封装两个播放器,暴露两个方法,方法内部调用各自的实现。
+1。这是最常规,也是最好维护,扩展的实现方式 接口申明:

/**
 * @description `播放器接口`:有需要扩展的方法时继续申明,并在对应的播放器类中实现即可
 */
interface IPlayer {
    /**
     * @description `播放`
     */
    play (): void
    /**
     * @description `暂停`
     */
    pause (): void
}
实际使用时,下面两个类是不需要写的,就是简单的申明了一下要调用的两个播放器(TxPlayer,EgamePlayer);我本地没有这俩货,为了后面代码不报错

class TxPlayer {
    constructor (options: Record<string, any>) {

    }

    play () {}

    pause () {}
}
class EgamePlayer {
    constructor (options: Record<string, any>) {

    }

    start () {}

    stop () {}
}
ziqi0716 2021-05-14
  • 打赏
  • 举报
回复
抽象出播放器接口,包含播放与停止两个函数。 封装两个播放器,暴露两个方法,方法内部调用各自的实现。
我爱小仙女 2021-05-14
  • 打赏
  • 举报
回复
确实看错了,封装成统一调用的要用策略模式去封装了吧

87,922

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧