JS实现单例模式的多种方案
JS实现单例模式的多种方案
今天在复习设计模式中的-创建型模式,发现JS实现单例模式的方案有很多种,稍加总结了一下,列出了如下的6种方式与大家分享
大体上将内容分为了ES5(Function)与ES6(Class)实现两种部分
单例模式的概念
- 一个实例只生产一次
- 保证一个类仅有一个实例,并提供一个访问它的全局访问点
方式1
利用instanceof判断是否使用new关键字调用函数进行对象的实例化
function User() {
if (!(this instanceof User)) {
return
}
if (!User._instance) {
this.name = '无名'
User._instance = this
}
return User._instance
}
const u1 = new User()
const u2 = new User()
console.log(u1===u2);// true
方式2
在函数上直接添加方法属性调用生成实例
function User(){
this.name = '无名'
}
User.getInstance = function(){
if(!User._instance){
User._instance = new User()
}
return User._instance
}
const u1 = User.getInstance()
const u2 = User.getInstance()
console.log(u1===u2);
方式3
使用闭包,改进方式2
function User() {
this.name = '无名'
}
User.getInstance = (function () {
var instance
return function () {
if (!instance) {
instance = new User()
}
return instance
}
})()
const u1 = User.getInstance()
const u2 = User.getInstance()
console.log(u1 === u2);
方式4
使用包装对象结合闭包的形式实现
const User = (function () {
function _user() {
this.name = 'xm'
}
return function () {
if (!_user.instance) {
_user.instance = new _user()
}
return _user.instance
}
})()
const u1 = new User()
const u2 = new User()
console.log(u1 === u2); // true
当然这里可以将闭包部分的代码单独封装为一个函数
在频繁使用到单例的情况下,推荐使用类似此方法的方案,当然内部实现可以采用上述任意一种
function SingleWrapper(cons) {
// 排除非函数与箭头函数
if (!(cons instanceof Function) || !cons.prototype) {
throw new Error('不是合法的构造函数')
}
var instance
return function () {
if (!instance) {
instance = new cons()
}
return instance
}
}
function User(){
this.name = 'xm'
}
const SingleUser = SingleWrapper(User)
const u1 = new SingleUser()
const u2 = new SingleUser()
console.log(u1 === u2);
方式5
在构造函数中利用new.target判断是否使用new关键字
class User{
constructor(){
if(new.target !== User){
return
}
if(!User._instance){
this.name = 'xm'
User._instance = this
}
return User._instance
}
}
const u1 = new User()
const u2 = new User()
console.log(u1 === u2);
方式6
使用static静态方法
class User {
constructor() {
this.name = 'xm'
}
static getInstance() {
if (!User._instance) {
User._instance = new User()
}
return User._instance
}
}
const u1 = User.getInstance()
const u2 = User.getInstance()
console.log(u1 === u2);
JS实现单例模式的多种方案的更多相关文章
- JS在线代码编辑器多种方案monaco-editor,vue-monaco-editor
前言 JavaScript在线代码编辑器. 需要代码提示,关键字高亮,能够格式化代码.(不需要在线运行) 简简单单的需求. 方案一: Monaco-editor 简介:微软的开源项目,开源中国上面的在 ...
- react项目中引入了redux后js控制路由跳转方案
如果你的项目中并没有用到redux,那本文你可以忽略 问题引入 纯粹的单页面react应用中,通过this.props.history.push('/list')就可以进行路由跳转,但是加上了redu ...
- 基础3:js实现继承的多种方式
js实现继承的多种方式 1. 原型链继承 function Parent() { this.name = 'xwk' } Parent.prototype.getName = function() { ...
- 前端js书写规范和维护方案
在网上看到一篇文章,写的是怎样来维护自己写的js.感觉挺不错的,感觉代码很漂亮,转之,代码如下: /** * Created by gerry.zhong on 2016/10/11. */ var ...
- 单例模式,多种实现方式JAVA
转载请注明出处:http://cantellow.iteye.com/blog/838473 第一种(懒汉,线程不安全): public class Singleton { private stati ...
- JS的单例模式
维基百科对单例模式的介绍如下: 在应用单例模式时,生成单例的类必须保证只有一个实例的存在,很多时候整个系统只需要拥有一个全局对象,才有利于协调系统整体的行为.比如在整个系统的配置文件中,配置数据有一个 ...
- 深入分析Java单例模式的各种方案
单例模式 Java内存模型的抽象示意图: 所有单例模式都有一个共性,那就是这个类没有自己的状态.也就是说无论这个类有多少个实例,都是一样的:然后除此者外更重要的是,这个类如果有两个或两个以上的实例的话 ...
- webVR全景图多种方案实现(pannellum,aframe,Krpano,three,jquery-vrview)
前言 有一篇文章我说了H5实现全景图预览,全景视频播放的原理,有需要的小伙伴可以自行去看一下 今天我就拿出我的实践干货出来,本人实测实测过 需求 老板:我需要可以上传全景图片,然后手机网站上都可以36 ...
- js获取IP地址多种方法实例教程
js获取IP地址方法总结 js代码获取IP地址的方法,如何在js中取得客户端的IP地址.原文地址:js获取IP地址的三种方法 http://www.jbxue.com/article/11338. ...
随机推荐
- [换根DP][倍增]luogu P5666 树的重心
题面 https://www.luogu.com.cn/problem/P5666 分析 对于一棵以i为根的树来说,它的重心必然在其size大于等于sumsize/2的子树中. 那么断掉一条边e(u, ...
- 推荐模型NeuralCF:原理介绍与TensorFlow2.0实现
1. 简介 NCF是协同过滤在神经网络上的实现--神经网络协同过滤.由新加坡国立大学与2017年提出. 我们知道,在协同过滤的基础上发展来的矩阵分解取得了巨大的成就,但是矩阵分解得到低维隐向量求内积是 ...
- 回忆那些年我玩过的ide,看看哪些你也玩过,看图回忆
闲来无聊,回忆一下这些年玩过的ide.看看哪些你也玩过. QBasic 第一个ide,兴奋程度也是最大的,从此进入了码农行列 VisualBasic 可以拖界面了,成就感爆棚 Turbo C c语言, ...
- [SpringCloud教程]3. Eureka服务注册中心集成
新微服务项目多半采用Nacos作为服务注册与发现中心,但是旧项目可能使用Eureka.zookeeper.Consul.Nacos作为服务注册中心. 新项目建议使用Nacos作为服务注册中心 Spri ...
- ASP.NET扩展库之Http日志
最佳实践都告诉我们不要记录请求的详细日志,因为这有安全问题,但在实际开发中,请求的详细内容对于快速定位问题却是非常重要的,有时也是系统的强力证据.Xfrogcn.AspNetCore.Extensio ...
- 创建线程的方式三:实现Callable接口 --- JDK 5.0新增
/** * 创建线程的方式三:实现Callable接口. --- JDK 5.0新增 * * * 如何理解实现Callable接口的方式创建多线程比实现Runnable接口创建多线程方式强大? * 1 ...
- 数栈SQL优化案例:隐式转换
MySQL是当下最流行的关系型数据库之一,互联网高速发展的今天,MySQL数据库在电商.金融等诸多行业的生产系统中被广泛使用. 在实际的开发运维过程中,想必大家也常常会碰到慢SQL的困扰.一条性能不好 ...
- python基础(补充):python三大器之生成器
生成器的定义 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后 ...
- MySQL提升笔记(3)日志文件详解
在MySQL数据库和InnoDB存储引擎中,有很多种文件,如:参数文件.日志文件.socket文件.pid文件.MySQL表结构文件.存储引擎文件. 本节重点关注日志文件,MySQL的复制.事务等重要 ...
- zk都有哪些使用场景?
(1)分布式协调:这个其实是zk很经典的一个用法,简单来说,就好比,你A系统发送个请求到mq,然后B消息消费之后处理了.那A系统如何知道B系统的处理结果?用zk就可以实现分布式系统之间的协调工作.A系 ...