先上实现:
// singleton.js
export default function singleton(className) {
let ins
return new Proxy(className,{
construct(target,argArray) {
if (!ins) {
ins = new target(...argArray)
}
return ins
}
})
}
这里利用了Proxy的construct配置属性拦截构造函数的new操作使用
使用:
Video.js
import singleton from './singleton';
class Video {
constructor() {
console.log('create');
}
}
const newVideo = new singleton(Video)
export { newVideo as Video }
// index.js
import {Video} from './Video.js';
const v1 = new Video()
const v2 = new Video()
console.log(v1 === v2); // true
为什么要这么写呢?因为:
我们一般这么实现单例模式:
// singleton.js
export default function singleton(className) {
let ins
//这里返回了一个新类
return class {
constuctor(...args){
if (!ins) {
ins = new className(...args)
}
return ins
}
})
}
使用起来也跟上面使用Proxy实现差不多,但是有一个弊病,就是不能操作原来类的原型对象,新增或修改里面的属性:
// index.js
import {Video} from './Video.js';
const v1 = new Video()
v1.prototype.play = function(){
console.log("play")
}
v1.play() //v1.play is not a function
原因是我们用singleton方法创建的实例,并不是原先Video类的实例,而是singleton方法返回的新类。这里往原型里面添加的方法是Video的原型上方法。使用Proxy的方法来实现能够有效的避免了这种情况。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。