设计模式,常见的模式有单例模式,代理模式等,设计模式的合理运用不仅使代码结构更加清晰,也便于后期的维护与重构。然而在日常的学习中,我们却在不经意间使用了单例模式,but总是容易忽视,额。。。应该是我,不是我们。
什么是单例模式?
限制一个类仅有一个实例化对象,并提供一个访问它的全局访问点。
经典的实现方式是:创建一个类,这个类包含一个方法,这个方法在没有对象存在的情况下,将会创建一个新的实例对象。如果对象存在,这个方法只是返回这个对象的引用
全局变量实现单例模式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>v-model</title> </head> <body> <div id="app">Btn</div> <script> // 通过全局变量实现单例模式 var instance document.getElementById('app').addEventListener('click', function() { if (!instance) { instance = new Person() } else { // console.log(instance) ==> 2 return instance } }) // instance = 22 </script> </body> </html>
全局变量在多人合作或者是项目复杂情况下,作为一个全局变量值容易被覆盖, 故不推荐
闭包实现单例模式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>v-model</title> </head> <body> <div id="app">Btn</div> <script> // 通过闭包实现单例模式 document.getElementById('app').addEventListener('click', function() { function Test(name) { var testData = this this.name = name Test = function() {
return testData } }
console.log(Test) var instance = new Test('yang')
console.log(Test)
var instance1 = new Test('fu') console.log(instance === instance1) // 闭包: 运行完一个函数,当前环境清除。而由于闭包的存在,依赖于的父级的环境,故变量值不会清空 }) </script> </body> </html>
当第一次调用构造函数后,Test被赋值为一个闭包,当再次调用构造函数时,返回的值为testData即为第一次调用构造函数的值(因为闭包的存在,变量值没有被清空)
使用构造函数的静态属性
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>v-model</title> </head> <body> <div id="app">Btn</div> <script> // 使用构造函数的静态属性 (当构造函数生成的两个实例全等于时,则证明为同一实例,即满足单例模式) document.getElementById('app').addEventListener('click', function() { function Test(name) {
if (typeof Test.instance === 'object') { return Test.instance } this.name = name; Test.instance = this; } var instance = new Test('yang') var instance1 = new Test('yan') console.log(instance === instance1) // Result: undefined , object, true }) </script> </body> </html>