单例模式的定义是:保证一个类仅有一个实例,并提供一个访问他的全局访问点。
单例模式是一种常见的模式,有一些对象我们往往只需要一个,比如线程池,全局缓存,浏览器中的window对象….
在 JavaScript 开发中,单例模式的用途同样的非常广泛。
例如,当用户单击登录按钮时,页面中就会出现一个登录浮框,而这个登录浮框应该是唯一的,无论单击多少次登录按钮,这个浮框都只会被创建一次。此时的这个场景就适合使用单例模式来创建。
要实现一个标准的单例模式,并不复杂,无非就是用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象。
示例代码如下:
// 返回能够创建单例的构造函数function getSingle(fn) {var instance = null;// 返回一个新的构造函数return function () {if (instance !== null) {// 如果已经存在实例对象,直接返回该实例对象return instance;}// 没有进入上面的 if,说明是第一次实例化对象// arguments 是调用这个新的构造函数所传入的参数 { '0': '张三', '1': 18 }// 方式一:// instance = new fn(...arguments);// return instance;// 思考:上面的 return instance 不写会怎么样?// 答案:会输出 undefined 张三 false// 原因:当外界 new 这个 function 的时候,会产生一个 {}(假设这个名字叫 A),然后隐式的返回这个对象 A// 然而你的这个 A 对象啥都没有,所以外界访问 p1.name 的时候,拿到的是 undefined// 而第二次之所以有值,是因为返回的是 instance,instance 的值存储的是 new fn(...arguments) 返回的对象// 方式二:this 是 new 这个 function 的时候会产生的一个对象,默认为空fn.apply(this, arguments);instance = this; // 将创建出来的实例对象赋值给 instance,下一次直接进入 if 然后 return// return this; // 隐式调用语句// return { name: 'xiejie' }; // 如果显式的返回一个对象,那么外界拿到的值是这个对象// 思考:书写 return { name: 'xiejie' } 后,外面依次打印出什么?// 答案:xiejie 张三 false 张三 false true// 原因:第一次 new 这个 function 的时候,instance 没有值,new 会生成一个空的 {}(假设这个名字叫 A)// fn.apply(this, arguments) 会执行 Person 里面的每一条语句,只不过 this 指向的是 A// 接下来将 A 这个对象赋值给 instance,然后本来该隐式返回 A 这个对象的,结果你显式返回了一个 {name: 'xiejie'}// 所以第一次 var p1 = new singlePerson('张三', 18) 拿到的是 {name: 'xiejie'} 这个对象// 然后第二次以及第三次 new singlePerson 的时候,因为 instance 里面有值了,所以直接返回 instance 存储的值// instance 存储的是 {name : '张三'}}}// 人类构造函数var Person = function (name, age) {this.name = name;this.age = age;}// 获取新的构造函数var singlePerson = new getSingle(Person);// 测试var p1 = new singlePerson('张三', 18);console.log(p1.name); // 张三var p2 = new singlePerson('李四', 20);console.log(p2.name); // 张三console.log(p1 === p2); // true// 书写了 return { name: 'xiejie' } 后进行测试// var p3 = new singlePerson('王五', 22);// console.log(p3.name); // 张三// console.log(p1 === p3); // false// console.log(p2 === p3); // true
我们来测试一下

我们可以看到我们单列模式创建成功了,此时这个singlePerson类我们只能创建一个,再次创建的话还是指向第一个实例创建的。
—————————————-其实在学到这里的,有一些不懂的地方搞懂了
比如apply是改变this执行的,第一个参数是this的指向,第二个参数是类数组或者数组
apply后面那个this在没有实例化之前执行win,实例化了之后指向实例化的对象
