之前我们学习构造函数的时候,经常会出现一个类,但是这些实例往往只是认为限制的,就是我们不需要多个实例
我们可以限制必须只能有一个实例,如果第二次创建的时候,我们可以抛出错误或者返回第一次的实例
比如下面的伪代码
1 function Person(name,age){ 2 this.name = name; 3 this.age = age; 4 } 5 var xiaoming = new Person(‘小明’,17); // 小明 6 var xiaohong = new Person(‘小红’,15); // 小红
最简单的单例模式就是设置一个属性(变量),这个属性标记着当前是已经被实例化过了
1 <script> 2 function Person(name, age) { 3 this.name = name; 4 this.age = age; 5 this.instance = null; 6 if (this.instance) { 7 return this.instance; 8 } 9 return this.instance = this; 10 } 11 var xiaoming = new Person('小明',17); // 小明 12 var xiaohong = new Person('小红',15); // 小红 13 console.log(xiaoming) 14 console.log(xiaohong) 15 </script>
上面的代码是一个错误的代码,因为标记不能是类的属性,因为类的属性是全新的,每一次你在new的时候都会创建一个新的属性,所以不可能实现单例状态
下面的代码是一个简单例模式的实现机制,就是利用IIFE执行一次的机制实现的
1 <script> 2 var Person = (function() { 3 var instance = null; 4 return function(name, age) { 5 this.name = name; 6 this.age = age; 7 if (instance) { 8 return instance; 9 } 10 return instance = this; 11 } 12 })(); 13 Person.prototype.sayHello = function() { 14 console.log(this.name) 15 }; 16 var xiaoming = new Person("小明", 12); 17 var xiaohong = new Person("小红", 13) 18 console.log(xiaoming) 19 console.log(xiaohong) 20 console.log(xiaoming == xiaohong) 21 xiaohong.sayHello() 22 xiaoming.sayHello() 23 </script>
此时我们的本质不是想真正的改变单例模式,而是想实现单例的机制,利用某个构造函数,此时我们可以用代理类来实现单例模式
1 <script> 2 function Person(name, age) { 3 this.name = name; 4 this.age = age; 5 } 6 Person.prototype.sayHello = function() { 7 console.log(this.name) 8 }; 9 // 设置一个代理类,实现单例模式 10 var PersonProxy = (function() { 11 var instance = null; 12 return function(name, age) { 13 if (instance) { 14 return instance 15 } 16 return instance = new Person(name, age) 17 } 18 })() 19 var xiaoming = new PersonProxy("小明", 12) 20 var xiaohong = new PersonProxy("小红", 13); 21 console.log(xiaoming) 22 console.log(xiaohong) 23 </script>