js单例模式

JS单例模式 (Singleton)

单例模式的核心是确保 一个特定类只有一个实例,并提供这个实例的全局访问

  1. 在构造函数的静态属性中缓存该实例

    function Sington() {
        if(typeof Sington.instance === 'object') {
            return Sington.instance
        }
        Sington.instance = this
        return this
    }
    
    var a = new Sington()
    var b = new Sington()
    console.log(a === b)	// true
    

    这种方式的缺点在于: instance 属性是公开可访问的属性,在外部代码中可能会修改该属性。

  2. 把实例封装在闭包中

    function Sington() {
        var instance = this
        // 重写构造函数
        Sington = function() {
            return instance
        }
    }
    
    var a = new Sington()
    var b = new Sington()
    console.log(a === b)	// true
    

    当第一次调用构造函数时,它正常返回 this ,然后在以后调用时,它将会执行重写构造函数,这个构造函数通过闭包访问了私有 instance 变量,并且简单的返回了该 instance

    这样可以保证该实例的私有性并且保证该实例不会在构造函数之外被修改,代价是带来了额外的闭包开销。

  3. 有时候对于单例对象需要延迟创建,所以在单例中还存在一种延迟创建的形式( 惰性单例)

    var Singleton = (function() {
      var instance
      Singleton = function() {
        if (instance) return instance
        return instance = this
      }
      return Singleton
    })()
    
    var a = new Singleton('a')
    var b = new Singleton('b')
    console.log(a===b)
    

    这种方法有缺点:不符合单一职责原则,这个对象其实负责了两个功能:单例和创建对象

  4. 改进版惰性单例

    var Singleton = function(Obj) {
    	var instance
    	Singleton = function(...args) {
    		if (instance) return instance
    		return (instance = new Obj(...args))
    	}
    	return Singleton
    }
    
    var People = function(name, age) {
        this.name = name
        this.age = age
    }
    
    var peopleSingleton = Singleton(People)
    
    var a = new peopleSingleton('a', 12)
    var b = new peopleSingleton('b', 11)
    console.log(a)	// People { name: 'a', age: 12 }
    console.log(b)	// People { name: 'a', age: 12 }
    console.log(a === b)	// true
    
  5. 单例模式应用场景 – 页面弹框

    <!DOCTYPE html>
    <html lang="en">
    	<head>
    		<meta charset="UTF-8" />
    		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
    		<title>Document</title>
    	</head>
    	<body>
    		<button id="loginBtn">click me</button>
    		<script>
    			var getSingle = function(fn) {
    				var result
    				return function() {
    					return result || (result = fn.apply(this, arguments))
    				}
    			}
    
    			var createLoginLayer = function() {
    				var div = document.createElement('div')
    				div.innerHTML = '我是登录浮窗'
    				div.style.display = 'none'
    				div.style.border = '1px solid #ccc'
    				document.body.appendChild(div)
    				return div
    			}
    			var createSingleLoginLayer = getSingle(createLoginLayer)
    			document.getElementById('loginBtn').onclick = function() {
    				var loginLayer = createSingleLoginLayer()
    				loginLayer.style.display = 'block'
    			}
    		</script>
    	</body>
    </html>
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值