浅谈JavaScript设计模式

2023-05-16

  1. 创建型模式 :该模式处理的是用于创建对象的各种机制
  • 工厂方法
  • 抽象工厂
  • 建造者
  • 原型
  • 单例
  1. 结构型模式:考虑的是对象的组成以及对象彼此之间的关系
  • 适配器
  • 桥接
  • 组合
  • 装饰器
  • 外观
  • 享元
  • 代理
  1. 行为型模式:关注的是对象之间的依赖关系以及通信
  • 解释器
  • 模板方法
  • 责任链
  • 命令
  • 迭代器
  • 中介者
  • 备忘录
  • 观察者
  • 状态
  • 策略
  • 访问者

  1. 模块模式
    var basic = {
      eniv: 'production',
      startupParam:{
        cache: 30,
        locale: 'en_US'
      },
      init: function(){
        console.log('init server')
      },
      update: function(params) {
        this.startupParam = params
           console.log(this.startupParam.cache)
           console.log('this.startupParam.locale')
      }
    }
    basic.init()      // init server
    basic.update({cache: 60, locale: 'en_UK'})      //60, en_UK

  2. 对上面的代码稍作改动,使用IIFE并返回模块接口
    var basic = (function (){
      var eniv = 'production';
      var startupParam = {
        cache: 30,
        locale: 'en_US'
      };
      return{
        init: function(){
          console.log('init server')
        },
        update: function(params) {
           this.startupParam = params
           console.log(this.startupParam.cache)
           console.log('this.startupParam.locale')
        }
      }
    })()
    basic.init()      // init server
    basic.update({cache: 60, locale: 'en_UK'})      //60,

  3. 对上面的模式再进行变形,不推荐在调用其他函数的公共函数或是公共变量的时候非得使用模块名,这种改进的模式也被称为RMP(暴露式模块模式),其背后主要的思路就是将所有的成员都定义在私有作用域中,使用指针返回一个匿名对象,该指针指向的私有功能需要公开暴露
    var basic = function() {
      var privateOne = 1;
      function privateFn() {
        console.log('private call');
      }
      var privateTwo = 2;
      function publicFn() {
        publicFnTwo();
      }
      function publicFnTwo() {
        privateFn();
      }
      function getCurrentState() {
        return 2;
        }
      return {
        setup: publicFn,
        count: publicTwo,
        increase: publicFnTwo,
        current: getCurrentState()
      }
    }()
    console.log(basic.current)    // 2
    basic.setup()  // private call


  4. 工厂模式
    function CarFactory() {}
    CarFactory.prototype.info = function() {
        console.log('info');
    }
    // 静态工厂方法
    CarFactory.make = function(type) {
        var constr = type;
        var car;
        CarFactory[constr].prototype = new CarFactory();
        car = new CarFactory[constr]();
        return car;
    }
    CarFactory.Compact = function(){
        this.doors = 4;
        this.engine_capacity = 2;
    }
    CarFactory.Sedan = function() {
        this.doors = 2;
        this.engine_capacity = 2;
    }
    CarFactory.SUV = function(){
        this.doors = 4;
        this.engine_capacity = 6;
    }
    var golf = CarFactory.make['Compact'];
    var vento = CarFactory.make['Sedan'];
    var touareg = CarFactory.make['SUV'];
    golf.info();    // info


  5. mixin模式
    mixin模式能够显著减少代码中重复出现的功能,有助于功能复用。这样你就可以将注意力放在构建实际功能上,而不是一再去重复那些可以共享的行为。
    var _ = require('underscore');
    var logger = (function () {
      var CustomLogger = {
        log: function (message) {
          console.log(message);
        }
      }
    }())
    // 需要定制的日志记录器来记录系统特定日志的对象
    var Server = (function (Logger) {
      var CustomServer = function() {
        this.init = function() {
          this.log(initial server);
        }
      }
      // 将CustomLogger的成员复制/扩展为CustomServer
      _.extend(CustomServer.prototype, Logger);
      return CustomServer;
    }(logger))
    (new Server()).init()  // initial server
    // 通过原型继承,将mixin的功能加入到对象中



    9.装饰器模式
    主要思想就是使用一个空白对象展开设计,该对象有一些基本的功能,随着设计的深入,可以使用现有的装饰器来增强该空白对象。
    // 实现最小化的BasicServer
    function BasicServer () {
      this.pid = 1;
      console.log('initial basic server');
      this.decorate_list = [];  // 空的装饰器列表
    }
    // 列出所有的装饰器
    BasicServer.decorators = {};
    // 将每个装饰器添加到BasicServer的装饰器列表中
    // 列表中的每个装饰器都会被应用到BasicServer实例
    BasicServer.decorators.reverseProxy = {
      init: function(pid){
        return pid + 1;
      }
    }
    BasicServer.decorators.servePHP = {
      init: function(pid) {
        return pid + 1;
      }
    }
    // 每次调用decorate()时,都将装饰器推入列表
    BasicServer.prototype.decorate = function(decorator) {
      this.decorate_list.push(decorator);
    }
    // init() 方法遍历所有应用于BasicServer的装饰器,在所有的装饰器上执行init()方法
    BasicServer.prototype.init = function () {
      var running_process = 0;
      var pid = this.pid;
      for(var i = 0; i < this.decorate_list.length; i++) {
        decorate_name = this.decorate_list[i];
        running_processes = BasicServer.decorators[decorate_name].init(pid);
        return running_process;
      }
    }
    // 创建提供reverseProxy代理的服务器
    var proxyServer = new BasicServer();
    proxyServer.decorate('reverseProxy');
    total_process = proxyServer.init()
    // 创建提供PHP服务的服务器
    var phpServer = new BasicServer()
    phpServer.decorate(servePHP)
    total_process = phpServer.init()



    10 观察者模式
    目标+观察者;在观察者模式中,目标保存了一个对其依赖的对象列表(称为观察者),并在自身状态发生变化时通知这些观察者,目标采用的通知方式是广播;观察者如果不想再被提醒,可以把自己从列表中移除。
    // 目标:能够添加,删除和提醒观察者目标
    var Subject = (function() {
      function Subject(){
        this.observer_list = [];
      }
      Subject.prototype.add_observer = function(obj){
        this.observer_list.push(obj)
      }
      Subject.prototype.remove_observer = function(obj) {
        for(var i = 0; i < this.observer_list.length; i++){
          if(this.observer_list[i] === obj) {
            this.observer_list.splice(i,1)
          }
        }
      }
      Subject.prototype.notify = function(){
        var args = Array.prototype.splice.call(arguments,0)
        for(var i = 0; i<this.observer_list.length;i++){
          this.observer_list[i].update(args)
        }
      }
      return Subject
    })()
    // 观察者
    function Tweeter(){
      var subject = new Subject()
      this.addObserver = function(observer){
        subject.add_observer(observer)
      }
      this.removeObserver = function(observer){
        subject.remove_observer(observer)
      }
      this.fetchTweets = function fetchTweets() {
        var tweet = {
          tweet: 'this is a abserver'
        }
        subject.notify(tweet)
      }
    }
    // 添加两名观察者
    var TweetUpdater = {
      update: function() {
        console.log('update tweet')
      }
    }
    var TweetFllower = {
      update: function() {
        console.log(Fllower tweet)
      }
    }
    // 此时我们就可以通过Tweeter的接口将观察者添加到Subject中了
    var tweetApp = new Tweeter()
    tweetApp.addObserver('TweetUpdater')
    tweetApp.addObserver('TweetFllower')
    tweetApp.fetchTweets()
    tweet.removeObserver(TweetUpdater)
    tweet.removeObserver('TweetFllower')

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

浅谈JavaScript设计模式 的相关文章

  • 隐藏/显示 DIV - 将当前效果更改为淡入淡出

    我目前正在使用网络教程中找到的以下代码来显示 隐藏 DIV 效果很好 但不喜欢这种效果 希望 DIV 淡入 淡出 或者更平滑的东西 目前 DIV 是从右上角增长的 我该如何调整代码来做到这一点 你可以在这里看到它http jsfiddle
  • 如何在 TypeScript 中获取源代码中的实际行号(用于自定义日志记录)

    参考文献这个问题 https stackoverflow com questions 1340872 how to get javascript caller function line number how to get javascri
  • Sequelize.js 中的自定义或覆盖连接

    我需要使用创建自定义连接条件Sequelize js http sequelizejs com使用 MSSQL 具体来说 我需要加入TableB基于一个COALESCE中的列的值TableA and TableB并最终得到这样的连接条件 L
  • Google reCaptcha 永远加载

    我在我的网站上使用 Google 的 reCaptcha 2 0 它曾经运行良好 但自从我向公众开放我的网站并获得了更多用户后 recaptcha 不再适用于大多数用户 它加载得很好 但一旦用户单击 我不是机器人 复选框 它会永远加载并且从
  • 如果浏览器在 asp .net 中关闭,请从浏览器中注销?

    我的要求有点复杂 用户正在使用 Web 浏览器访问数据库 而在访问数据库时 如果用户关闭活动页面而不是注销会话 该会话需要自动注销 有人可以指导我如何做这个吗 我在母版页中使用了jquery onbeforeunload 我收到消息离开页面
  • 动态表中每个按钮的 Jquery-Ui 对话框表单

    我正在生成一个 HTML 表 每行都有一个按钮 必须打开 Jquery ui 对话框表单 The table table class table table reporting table condensed table striped t
  • jQuery 验证日期范围问题

    我的代码中有很多地方有成对的相关开始和结束日期字段 范围 我需要验证开始日期早于结束日期 我正在使用 jQuery 验证插件 这是我的代码 http jsfiddle net jinglesthula dESz2 http jsfiddle
  • 光滑的旋转木马不工作

    我一直在尝试简单地实现 Slick Carousel 的工作 我已按照 Git 页面上的说明进行操作 https github com kenwheeler slick https github com kenwheeler slick 这
  • Rails 递归地包含 javascripts 资源文件夹

    我了解如何将一个 JavaScript 文件添加到 Rails 资产管道中 只需添加 require filename 到 application js 但是如何在一个文件夹下包含多个 javascript 文件 vendor assets
  • 离子旋转器未显示

    我用 http 请求填充 Ionic 集合重复列表 但我不想将所有内容直接加载到 DOM 中 因此 我只显示其中一些项目 并在您向下滚动时添加其余项目 为此我实现了无限滚动功能 当我到达页面底部时 它应该显示一个旋转器 但它没有 这些物品至
  • 如何将函数传递给 JavaScript Web Worker

    我想通过一个 或多个 函数传递postMessage 给网络工作者 因为我无法引用常规文件 为了启动 Web Worker 我将一个对象 URL 从 Blob 创建 传递给Worker构造函数 然后我传递一条消息 但到目前为止还没有在消息中
  • 在 HTML5 中将两个图像合并到一个画布上

    我正在使用 HTML5 canvas 元素 假设我有 2 个 ImageData 对象 我想将它们组合起来放在一张画布上 假设我不关心这些图像如何组合 两个 ImageData 对象具有完全相同的像素数和形状 组合两个图像的最佳方式是什么
  • ReferenceError 和全局对象

    在浏览器中的 JavaScript 中window是全局对象 这意味着在全局范围内定义的每个变量都是window 那么为什么我会得到这个结果 console log window foo No error logs undefined co
  • 显示班级图片 10 秒

    我有下面给出的代码显示9 boxes 其值如下digital time 还有一个班级box002显示digits相当于随机选择的九个盒子的值 box002 can be dragged to digital time starting wi
  • 父指令属性更改时子指令不会更新

    这是对这两个问题的后续 在父指令和子指令之间传递参数 https stackoverflow com questions 42814530 pass argument between parent and child directives
  • 如何从配置加载套接字 io 事件监听器? [复制]

    这个问题在这里已经有答案了 我有使用套接字io 的nodejs 应用程序 我将存储在 config routes js 中的所有事件侦听器 module exports routes auth login controller auth a
  • 使用 JavaScript onclick 添加表格行

    我正在尝试使用 javascript 添加下面找到的完全相同的元素 我已经尝试了这里找到的所有解决方案 我什至尝试用php echo但没有运气 无需更改任何输入名称或类似内容 只需单击该按钮即可向表中添加另一行 仅此而已 这是该元素 tr
  • 如何设置 Firebase 用户的显示名称?

    根据Firebase网站上的JS Auth文档 它只展示了如何获取 displayName 以及如何更新 displayName 所以我尝试更新它 但这有点不合逻辑 因为你怎么能在不创建某些东西的情况下更新它呢 所以我的问题是 如何设置注册
  • openssl_pkey_get_details($res) 不返回公共指数

    我在用着这个例子 https stackoverflow com a 12575951 2016196使用 php 生成的密钥进行 javascript 加密openssl图书馆 但是 details openssl pkey get de
  • 使用 JQuery 预填充选择字段的下拉选项验证

    我有这个 JQuery 片段来防止选择已在另一个字段中选择的下拉选项 var coll select name service on change function coll each function var val this value

随机推荐

  • VmWare虚拟机设置ubuntu和windows之间的共享文件夹

    一般在进行编程作业的时候 xff0c 我们会采用 开发在Windows中编辑源代码 xff0c 在linux中编译 执行源代码 这往往需要需要将在Windows下编辑好的源代码上传到linux系统种进行编译 怎么来进行上传呢 xff1f 其
  • C++的最后一道坎|百万年薪的程序员

    导语 C 43 43 的起源可以追溯到 40 年前 xff0c 但它仍然是当今使用最广泛的编程语言之一 xff0c C 43 43 发明人Bjarne Stroustrup 一开始没想到 C 43 43 会获得如此大的成功 xff0c 他说
  • Modbus 协议

    1 主站 xff1a 可以进行读写操作 从站 xff1a 只能被动响应主站操作 2 一个 Modbus 网络只有一个主站 xff0c 可以多个从站 xff08 主站不用连在两端 xff09 485 通讯 1 接线 最多 254 个站 xff
  • 数据结构对齐

    xfeff xfeff 对齐的算法 xff1a 由于各个平台和编译器的不同 xff0c 现以本人使用的gcc version 3 2 2编译器 xff08 32位x86平台 xff09 为例子 xff0c 来讨论编译器对struct数据结构
  • 关于示波器测485串口波特率的使用方法总结

    之前没有用过示波器 xff0c 更不知道怎么来测试串口的波特率 xff0c 结果遇到一客户说我们产品的波特率达不到9600 xff0c 只有9100 xff0c 为了验证这一说法 xff0c 我们只能自己测试一下 说明 xff1a 产品通过
  • C语言对寄存器封装

    一 封装外设 用C语言代码把外设地址映射用宏定义封装 span class hljs comment 外设基地址 span span class hljs preprocessor define PERIPH BASE unsigned i
  • JavaJDK下载安装与环境配置(Windows 10 超详细的图文版教程 )

    前言 xff1a 对于很多初学者来说 xff0c 我想可能很多人都会遇到JDK环境变量的配置问题 明明就是按照度娘上的教程去一步步配置的 xff0c 但还是会有很多的人出现配置不成功的问题 所以今天在这里分享一下windows 10 系统下
  • win32 获取窗口句柄的方法

    第一种方法是根据窗口句柄值获取窗口句柄 使用spy 43 43 获取指定窗口的窗口句柄值 xff0c 因为句柄值是16进制数 xff0c 所以前面加0x 然后进行强制转换为HWND类型 HWND hWnd 61 HWND 0x0028072
  • 当设置display:inline;时li的宽度无效的解决方法

    若制作导航栏时 xff0c 使用列表li 的定义时 xff0c 若想加上一个背景图 xff0c 这时候若定义li的一个属性为 li display inline width 83px height 30px xff0c 则浏览器会无视后面的
  • js文本框或者按钮鼠标悬停提示说明文字

    html页面中很多元素会用到文本提示 xff0c 当鼠标悬停之后显示一段说明文字 显示说明性文字 function tips id str t 61 getTop document getElementById id document ge
  • localstorage兼容ie8以下浏览器的问题

    最近在做一个网站 xff0c 由于希望尽可能减小服务器的压力 xff0c 也想提高网站的运转速度 xff0c 就想尽可能少的在服务器上读写数据以及下载重复数据 xff0c 需要重复使用的数据 xff0c 就储存在本地 xff0c 能在本地进
  • HTTP请求返回状态码中301与302的状态码区别

    一 xff0e 官方说法 301 xff0c 302 都是HTTP状态的编码 xff0c 都代表着某个URL发生了转移 xff0c 不同之处在于 xff1a 301 redirect 301 代表永久性转移 Permanently Move
  • java防止 csrf 攻击 --- 采用 spring .

    CSRF xff08 Cross site request forgery xff09 xff0c 中文名称 xff1a 跨站请求伪造 xff0c 也被称为 xff1a one click attack session riding xff
  • Gson解析数组多类型元素

    why used gson Gson is a Java library that can be used to convert Java Objects into their JSON representation It can also
  • js中获取时间new Date()详细介绍

    1 var myDate 61 new Date Date 返回当日的日期和时间 getDate 从 Date 对象返回一个月中的某一天 1 31 getDay 从 Date 对象返回一周中的某一天 0 6 getMonth 从 Date
  • 如何让一个行内元素(如一张图片)在div中居中

    xff08 1 xff09 第一种 xff1a 用vertical align lt div class 61 34 method1 34 gt lt span class 61 34 tiptop 34 gt lt span gt lt
  • 释放webpack tree-shaking潜力之webpack-deep-scope-analysis-plugin

    在上周末广州举办的 feday 中 webpack 的核心开发者 Sean 在介绍 webpack 插件系统原理时 隆重介绍了一个中国学生于 Google 夏令营 在导师 Tobias 带领下写的一个 webpack 插件 https gi
  • iframe跨域通信的通用解决方案

    此方案已有新版本 请查看 iframe跨域通信的通用解决方案 第二弹 xff08 终极解决方案 xff09 本文章可做技术学习供继续交流 一 背景 在这个Web页面越来越丰富的时代 xff0c 页面通过iframe嵌入其他的页面也越来越常见
  • C++实现轻量级RPC分布式网络通信框架

    前言 xff1a 2022 4 14更新 xff1a 在我重新回顾这篇文章的时候 xff0c 我觉得里面内容有点乱 xff0c 主要还是因为RPC里面涉及到很多概念和知识点 本来代码内容就已经挺抽象了 xff0c 还要结合各种概念 xff0
  • 浅谈JavaScript设计模式

    创建型模式 xff1a 该模式处理的是用于创建对象的各种机制 工厂方法抽象工厂建造者原型单例 结构型模式 xff1a 考虑的是对象的组成以及对象彼此之间的关系 适配器桥接组合装饰器外观享元代理 行为型模式 xff1a 关注的是对象之间的依赖