乐趣区

关于javascript:在js中使用Proxy来相对可靠地实现单例模式

先上实现:

// 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 的办法来实现可能无效的防止了这种状况。

退出移动版