浅谈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设计模式 的相关文章

  • 上传时自动缩小 CSS 和 Javascript

    有谁知道通过上传处理 脚本自动运行某些文件类型的好方法 当我将 CSS 和 Javascript 上传到服务器时 我试图自动缩小它们 在本地保留一个漂亮的 人类可读的版本 同时在服务器上保留一个缩小的版本 我目前在 Windows 上使用
  • Javascript 闭包与 PHP 闭包,有什么区别?

    JS 中的闭包和 PHP 中的闭包有什么区别 它们的工作方式几乎相同吗 在 PHP 中编写闭包时有什么需要注意的注意事项吗 一个区别是两者如何处理存储执行匿名函数的上下文 JavaScript var a 1 var f function
  • Google 地图上的自定义路线/路径/道路

    我需要能够使用 V2 或 V3 最好是 3 创建在某种意义上忽略建筑物的路径 我试图创建一个 kml 文件来自己绘制所有路径 然后找到某种方法根据需要打开 关闭它们 例如 用户想要从 A 点前往 B 点 这些点之间有许多建筑物 用户可以实际
  • 在承诺中运行同步函数

    我是 JS 和异步操作的新手 在使用express的nodeJS路由器中 我使用mongoose从mongo聚合了一些数据 该数据是每隔 15 分钟从不同站点收集的天气数据 我使用猫鼬聚合管道处理数据 以获取每小时数据并按每个站点进行分组
  • 访问 .js 文件中的 Nuxt 插件

    假设我有一个脚本文件 foo js function doStuff how to access store and other plugins here export default doStuff 如果不将调用组件作为参数传递 我如何访
  • 每次用户在地址栏中按 Enter 时,Firefox 插件都会执行某些操作

    我正在尝试编写一个扩展程序 用于监视每次有人在使用地址栏时按下回车键时的情况 步骤将类似于 用户在地址栏中输入一堆文本并按 Enter 键 我的插件启动并接收用户输入的内容 然后我的插件决定如何处理用户输入的字符串 我通过使用在步骤 2 中
  • 显示来自 mongodb 的所有数据并在 doT.js 模板引擎中渲染它

    我想从 mongodb 中提取数据并将其传递给视图 一切似乎都正常 但我没有看到所有 10000 条记录都显示出来 而是只看到了一条 我觉得我非常接近解决它 但我陷入困境 我正在使用node mongodb native express和d
  • HTML5 游戏到本机应用程序 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在用 HTML5 制作游戏 我最熟悉 HTML5 并且比 C 等更高级的语言更喜欢它 HTML5
  • 基于 json 文件动态显示选择、复选框、日期选择器等

    对我之前的问题的补充 我根据 json 文件动态显示输入字段 现在我想根据它们的组显示选择项 复选框和日期选择器 我如何解决这个问题 我需要将这些元素推入computeJSON 但写入例如选择options item selection不管
  • 如何将js文件从同一文件夹导入chrome扩展中的background.js

    我在导入与 background js 脚本库 位于同一库中的文件 score js 时遇到问题 我对 js 和 chrome 扩展都很陌生 我研究了 require js 并做了这个 背景 html h1 Tab Manager h1
  • Javascript:更改浏览器后退按钮的功能

    有没有办法让用户的浏览器上的后退按钮调用 JavaScript 函数而不是返回页面 您无法覆盖这样的行为 如果用户通过链接访问您的页面 则单击 后退 将使他们再次离开该页面 但是 您可以使页面上的 JavaScript 操作将条目添加到历史
  • ES6 生成器——它们真的是 async/await 的替代品吗?

    评论区的帖子之一this http blogs msdn com b typescript archive 2014 10 22 typescript and the road to 2 0 aspx打字稿博客文章说 如果我必须等到 2 0
  • 如何将这段 javascript 代码重写为 C++11?

    这是我在 Javascript Definitive Guide 中看到的 javascript 闭包代码 我想把它写成C 11 var uniqueID1 function var id 0 return function return
  • 使用 jQuery animate 时,有没有办法隐藏 webkit 浏览器中显示的工件?

    我正在使用 jQuery animate 在网页上的项目中滑动 由于某种原因 只有在 webkit 浏览器中 元素动画的空间中才会出现伪影痕迹 有没有办法阻止或隐藏这种情况 一旦您加载此处的页面 它们就会出现在轮播上 http www my
  • NodeJS 错误堆栈未定义 [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在使用节点检查器 我注意到new Error 有未定义的堆栈 如果我将此值分配给一个变量 该变量将显示堆栈未定义 有趣的是 跑步new
  • jQuery 更改为隐藏字段后触发重力表单中的表单更新

    简而言之 是否有 JavaScript 函数或挂钩来触发重力形式的更新 以便执行条件逻辑 原问题 我正在使用重力形式 并且创建了一个 变化时 事件 gform 1 find gfield date dropdown month select
  • 出于安全目的,您是否有理由不执行自己的算法来打乱 ID?

    我计划实现我自己的非常简单的 哈希 公式 为具有多个用户的应用程序添加一层安全性 我目前的计划如下 用户创建一个帐户 此时后端会生成一个 ID ID 通过公式运行 假设 ID 57 8926 36 7 或同样随机的东西 然后 我将新的用户
  • jQuery 倒计时插件 - 只显示非零周期

    我正在使用 jQuery 倒计时插件编写倒计时 我只希望它显示活动 非零 周期 例如代替 剩余时间 0 天 0 小时 13 分 20 秒 它应该只显示 13 分 20 秒 我的代码是 countdown countdown expiryUr
  • Javascript 最佳实践,为什么使用逗号来链接函数/变量声明?

    我一直在为 jQuery jQueryLog 开发一个插件 以允许调试链选择器和返回值 如果你想检查一下 你可以这样做here http www jquerylog com 这已经是第二个版本了 第一个版本实际上是经过编辑的 jQuery
  • 在哪里放置资源特定逻辑

    您能帮我考虑在 AngularJS 中将资源 服务 特定的业务逻辑放置在哪里吗 我觉得在我的资源上创建一些类似模型的抽象应该很棒 但我不确定如何做 API调用 gt GET customers 1 lt first name John la

随机推荐

  • 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 关注的是对象之间的依赖