单例模式也称为单体模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。如何用js实现单例模式呢,本文使用es6的语法带你一步步的实现一个单例模式。
js
class MyVideo {
constructor() { }
static _ins;
static singleInstance () {
if (!this._ins) {
this._ins = new MyVideo()
}
return this._ins;
}
}
const v1 = MyVideo.singleInstance()
const v2 = MyVideo.singleInstance()
console.log(v1 === v2); // true

上面就是一个最简单不过的单例模式,然而这真能保证全局实例唯一吗,显然当然不能,因为使用者完全可以使用new MyVideo()的用法
es6可以用模块的写法,暴露一个实例
改进方案一
class MyVideo { constructor() { } static _ins; static singleInstance () { if (!this._ins) { this._ins = new MyVideo() } return this._ins; } } export default MyVideo.singleInstance()
import myVideo from "./js/video" const v2 = new myVideo.constructor() console.log(myVideo === v2); // false
使用者依然可以通过构造函数创建新的实例
接下来使用es6的proxy实现一个通用的单例模式包装函数,将任意class包装成单例
封装通用函数single.js
jsexport function singletonWrap (className) {
let ins
const proxy = new Proxy(className, {
construct (target, args) {
if (!ins) {
console.log("construct");
ins = new className(...args)
} else {
console.warn(`${className}只有一个实例`);
}
return ins
}
})
// 修改原型链,防止通过构造函数创建新的实例
className.prototype.constructor = proxy
return proxy
}
在MyVideo.js使用singletonWrap将MyVideo变成单例
import { singletonWrap } from "./single" class MyVideo { constructor() { } } export default singletonWrap(MyVideo)


本文作者:千寻
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!