单例模式——面试真题

下面我们通过平时遇到的面试题继续巩固一下昨天学的单例模式。

  • 描述

    实现Storage,使得该对象为单例,基于 localStorage 进行封装。实现方法 setItem(key,value) 和 getItem(key)。

  • 思路
    首先我们单例模式最主要的就是有这么一个instance的东西,然后判断一下有就返回,没有就将instance指向当前对象。
class Storage {
    static getInstance(){
       //判断是否有一个实例
       if(!Storage.instance){
         // 若这个唯一的实例不存在,那么先创建它
          Storage.instance = new Storage()
       }
      // 若这个唯一的实例存在,那么直接返回实例
       return Storage.instance
    }
    setStoreItem(key, val){
        localStorage.setItem(key, val)
    }
    getStoreItem(key){
      return localStorage.getItem(key)
    }
  }
  const storage1 = Storage.getInstance()
  const storage2 = Storage.getInstance()

  storage1.setItem('name', '李雷')
  // 李雷
  storage1.getItem('name')
  // 也是李雷
  storage2.getItem('name')

  // 返回true
  storage1 === storage2

当然你也可以通过原型和闭包来实现单例模式

function StorageBase(){}
StorageBase.prototype.getItem = function(key){
  return localStorage.getItem(key)
}
StorageBase.prototype.setItem = function(key, value){
  localStorage.setItem(key,value)
}
let Storage = (function(){
  let instance  = null
  return function(){
    if(!instance){
      instance = new StorageBase()
    }
    return instance
  }
})()
// 这里其实不用 new Storage 的形式调用,直接 Storage() 也会有一样的效果 
const storage1 = new Storage()
const storage2 = new Storage()

storage1.setItem('name', '李雷')
// 李雷
storage1.getItem('name')
// 也是李雷
storage2.getItem('name')

// 返回true
storage1 === storage2

实现一个全局的模态框

  • 思路
    万变不离其踪,记住getInstance方法、记住instance变量、记住闭包和静态方法,这个题除了要多写点 HTML 和 CSS 之外,对大家来说完全不成问题。
  <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>单例模式弹框</title>
</head>
<style>
    #modal {
        height: 200px;
        width: 200px;
        line-height: 200px;
        position: fixed;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        border: 1px solid black;
        text-align: center;
    }
</style>
<body>
	<button id='open'>打开弹框</button>
	<button id='close'>关闭弹框</button>
</body>
<script>
    // 核心逻辑,这里采用了闭包思路来实现单例模式
    const Modal = (function() {
    	let modal = null
    	return function() {
            if(!modal) {
            	modal = document.createElement('div')
            	modal.innerHTML = '我是一个全局唯一的Modal'
            	modal.id = 'modal'
            	modal.style.display = 'none'
            	document.body.appendChild(modal)
            }
            return modal
    	}
    })()
    
    // 点击打开按钮展示模态框
    document.getElementById('open').addEventListener('click', function() {
        // 未点击则不创建modal实例,避免不必要的内存占用;此处不用 new Modal 的形式调用也可以,和 Storage 同理
    	const modal = new Modal()
    	modal.style.display = 'block'
    })
    
    // 点击关闭按钮隐藏模态框
    document.getElementById('close').addEventListener('click', function() {
    	const modal = new Modal()
    	if(modal) {
    	    modal.style.display = 'none'
    	}
    })
</script>
</html>

参考掘金小册《JavaScript 设计模式核⼼原理与应⽤实践》

posted @ 2021-11-05 11:45  自在一方  阅读(362)  评论(0编辑  收藏  举报