iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >JavaScript中常见的反模式是什么
  • 462
分享到

JavaScript中常见的反模式是什么

2024-04-02 19:04:59 462人浏览 薄情痞子
摘要

本篇内容主要讲解“javascript中常见的反模式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中常见的反模式是什么”吧!硬编码硬编

本篇内容主要讲解“javascript中常见的反模式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中常见的反模式是什么”吧!

硬编码

硬编码(Hard-coding)的字符串、数字、日期…… 所有能写死的东西都会被人写死。 这是一个妇孺皆知的反模式,同时也是最广泛使用的反模式。 硬编码中最为典型的大概是 平台相关代码(PlatfORM-Related), 这是指特定的机器或环境下才可以正常运行的代码, 可能是只在你的机器上可以运行,也可能是只在 windows 下可以运行。

例如在 npm script 中写死脚本路径 /Users/harttle/bin/fis3, 原因可能是安装一次非常困难,可能是为了避免重复安装,也可能仅仅是因为这样好使。 不管怎样,这会让所有同事来找你问“为什么我这里会报错”。 解决办法就是把它放到依赖管理,如果有特定的版本要求可以使用 package-lock,如果实在搞不定可以视为外部依赖可以放到本地配置文件并从版本控制(比如 git) 移除。

例如在 cli 工具中写死特殊文件夹 /tmp, ~/.cache,或者路径分隔符 \\ 或 /。 这类字符串一般可以通过 node.js 内置模块(或其他运行时 api)来得到, 比如使用 os.homedir, os.tmpdir, path.sep 等。

重复代码

重复代码(Duplication)在业务代码中尤为常见,初衷几乎都是维护业务的稳定性。 举个例子:在页面 A 中需要一个漂亮的搜索框,而页面 B 中恰好有一个。 这时程序员小哥面临一个艰难的选择(如果直接拷贝还会有些许感到不安的话):

  • 把 B 拷贝一份,改成 A 想要的样子。

  • 把 B 中的搜索框重构到 C,B 和 A 引用这份代码。

由于时间紧迫希望早点下班,或者由于改坏 B 需要承担责任 (PM:让你做 A 为啥 B 坏了?回答这个问题比较复杂,这里先跳过), 经过一番思考后决定采取方案 2。

至此整个故事进行地很自然也很顺利,这大概就是重复代码被广泛使用的原因。 这个故事中有几点需要质疑:

  • B 这么容易被改坏,说明 B 的作者 并未考虑复用。这时不应复用 B 的代码,除非决定接手维护它。

  • B 改坏的责任不止程序员小哥:B 的作者是否有 编写测试,测试人员是否 回归测试 B 页面?

  • 时间紧迫不必然导致反模式的出现,不可作为说服自己的原因。短期方案也存在优雅实现。

解决办法就是:抽取 B 的代码重新开发形成搜索框组件 C,在 A 页面使用它。 同时提供给日后的小伙伴使用,包括敦促 B 的作者也迁移到 C 统一维护。

假 AMD

模块化本意是指把软件的各功能分离到独立的模块中,每个模块包含完整的一个细分功能。 在 JavaScript 中则是特指把脚本切分为独立上下文的,可复用的代码单元。

由于 JavaScript 最初作为页面脚本,存在很多引用全局作用域的语法,以及不少基于全局变量的实践方式。 比如 Jquery 的 $, BOM 提供的 window,省略 var 来定义变量等。 AMD 是 JavaScript 社区较早的模块化规范。这是一个君子协定,问题就出在这里。 有无数种方式写出假的 AMD 模块:

  • 没有返回值。对,要的就是副作用。

  • define 后直接 require。对,要的就是立即执行。

  • 产生副作用。修改 window 或其他共享变量,比如其他模块的静态属性。

  • 并发问题。依赖关系不明容易引发并发问题。

全局副作用的影响完全等同于全局变量,几乎有全局变量的所有缺点: 执行逻辑不容易理解;隐式的耦合关系;编写测试困难。下面来一个具体的例子:

  // file: login.js

  define('login', function () {

  fetch('/account/login').then(x => {

  window.login = true

  })

  })

  require(['login'])

这个 AMD 模块与直接写在一个 <script> 并无区别,准确地说是更不可控(requirejs 实现是异步的)。 也无法被其他模块使用(比如要实现注销后再次登录),因为它没返回任何接口。 此外这个模块存在并发问题(Race Condition):使用 window.login 判断是否登录不靠谱。

解决办法就是把它抽象为模块,由外部来控制它的执行并获得登录结果。 在一个模块化良好的项目中,所有状态最终由 APP 入口产生, 模块间共享的状态都被抽取到最近的公共上级。

  define(function () {

  return fetch('/account/login')

  .then(() => true)

  .catch(e => {

  console.error(e)

  return false

  }

  })

注释膨胀

注释的初衷是让读者更好的理解代码意图,但实践中可能恰好相反。直接举一个生活中的例子:

  // 判断手机百度版本大于 15

  if (navigator.userAgent.match(/Chrome:(\d+))[1] < 15) {

  // ...

  }

哈哈当你读到这一段时,相信上述注释已经成功地消耗了你的时间。 如果你第一次看到这样的注释可能会不可思议,但真实的项目中多数注释都是这个状态。 因为维护代码不一定总是记得维护注释,况且维护代码的通常不止一人。 C 语言课程的后遗症不止变量命名,“常写注释”也是一个很坏的教导。

解决办法就是用清晰的逻辑来代替注释,上述例子重新编写后的代码如下:

  if (ishttpsSupported()) {

  // 通过函数抽取 + 命名,避免了添加注释

  }

  function isHttpsSupported() {

  return navigator.userAgent.match(/Chrome:(\d+))[1] < 15

  }

函数体膨胀

“通常”认为函数体膨胀和全局变量都是算法课的后遗症。 但复杂的业务和算法的场景确实不同,前者有更多的概念和操作需要解释和整理。 整理业务逻辑最有效的手段莫过于变量命名和方法抽取(当然,还要有相应的闭包或对象)。

但在真实的业务维护中,保持理性并不容易。 当你几十次进入同一个文件添加业务逻辑后,你的函数一定会像懒婆娘的裹脚布一样又臭又长:

  function submitForm() {

  var username = $('form input#username').val()

  if (username === 'harttle') {

  username = 'God'

  } else {

  username = 'Mortal'

  if ($('form input#Words').val().indexOf('harttle')) {

  username = 'prophet'

  }

  }

  $('form input#username').val(username)

  $('form').submit()

  }

这只是用来示例,十几行还远远没有达到“又臭又长”的地步。 但已经可以看到各种目的的修改让 submitForm() 的职责远不止提交一个表单。 一个可能的重构方案是这样的:

  function submitForm() {

  normalize()

  $('form').submit()

  }

  function normalize() {

  var username = parseUsername(

  $('form input#username').val(),

  $('form input#words').val()

  )

  $('form input#username').val(username)

  }

  function parseUsername(username, words)

  if (username === 'harttle') {

  return 'God'

  }

  return words.indexOf('harttle') ? 'prophet' : 'Mortal'

  }

在重构后的版本中,我们把原始输入解析、数据归一化等操作分离到了不同的函数, 这些抽离不仅让 submitForm() 更容易理解,也让进一步扩展业务更为方便。 比如在 normalize() 方法中对 input#password 字段也进行检查, 比如新增一个 parseWords() 方法对 input#words 字段进行解析等等。

到此,相信大家对“JavaScript中常见的反模式是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: JavaScript中常见的反模式是什么

本文链接: https://www.lsjlt.com/news/85405.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript中常见的反模式是什么
    本篇内容主要讲解“JavaScript中常见的反模式是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript中常见的反模式是什么”吧!硬编码硬编...
    99+
    2024-04-02
  • Python常见的反模式有哪些
    本篇内容介绍了“Python常见的反模式有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.对Iterable对象使用map()和fil...
    99+
    2023-06-15
  • Vim的三种常见模式是什么
    这篇文章主要介绍了Vim的三种常见模式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vim的三种常见模式是什么文章都会有所收获,下面我们一起来看看吧。安装VIM# yum instal...
    99+
    2023-06-28
  • php常见运行模式是什么
    本篇内容介绍了“php常见运行模式是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、CGI允许web服务器通过特定的协议与应用程序进行...
    99+
    2023-06-30
  • Python编程中的反模式是什么
    Python编程中的反模式是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。这篇文章收集了我在Python新手开发者写的代码中所见到的不规范但偶尔又很微妙的问题。本文的目的是...
    99+
    2023-06-17
  • 一文总结JavaScript中常见的设计模式
    目录设计原则什么是设计模式一、单例模式二、策略模式三、代理模式四、迭代器模式五、发布-订阅模式六、命令模式七、组合模式八、模板方法模式九、享元模式十、职责链模式十一、中介者模式十二、...
    99+
    2023-05-19
    JavaScript设计模式 JavaScript设计
  • JavaScript中常见的八个陷阱是什么
    这篇文章给大家分享的是有关JavaScript中常见的八个陷阱是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1. 你是否尝试过对数组元素进行排序?JavaScript默认使...
    99+
    2024-04-02
  • 常见PHP设计模式之间的区别是什么
    这篇文章主要介绍了常见PHP设计模式之间的区别是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇常见PHP设计模式之间的区别是什么文章都会有所收获,下面我们一起来看看吧。一、单例模式单例模式是一种常见的设计模...
    99+
    2023-07-05
  • JavaScript中设计模式是什么
    这篇文章主要介绍了JavaScript中设计模式是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。设计模式是任何优秀软件的基础,JavaScript 也不例外,学习设计模式...
    99+
    2023-06-20
  • JavaScript中什么是装饰者模式
    本篇文章为大家展示了JavaScript中什么是装饰者模式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。JavaScript有什么特点1、js属于一种解释性脚本语言;2、在绝大多数浏览器的支持下,j...
    99+
    2023-06-14
  • Python常见异常的处理方式是什么
    这篇文章主要介绍“Python常见异常的处理方式是什么”,在日常操作中,相信很多人在Python常见异常的处理方式是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python常见异常的处理方式是什么”的疑...
    99+
    2023-07-05
  • JavaScript中介者模式的作用是什么
    这篇文章给大家介绍JavaScript中介者模式的作用是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。JavaScript有什么特点1、js属于一种解释性脚本语言;2、在绝大多数浏览器的支持下,js可以在多种平台下...
    99+
    2023-06-14
  • JavaScript中策略模式的作用是什么
    本篇文章为大家展示了JavaScript中策略模式的作用是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。JavaScript是什么JavaScript是一种直译式的脚本语言,其解释器被称为Jav...
    99+
    2023-06-14
  • JavaScript中五大常见函数分别是什么
    这篇文章主要为大家展示了“JavaScript中五大常见函数分别是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JavaScript中五大常见函数分别是什么...
    99+
    2024-04-02
  • JavaScript中常见加密解密方法是什么
    这篇文章主要介绍了JavaScript中常见加密解密方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript中常见加密解密方法是什么文章都会有所收获,下面我们一起来看看吧。安装npm ins...
    99+
    2023-07-05
  • 什么是Javascript工厂模式
    这篇文章主要介绍“什么是Javascript工厂模式”,在日常操作中,相信很多人在什么是Javascript工厂模式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”什么是Jav...
    99+
    2024-04-02
  • 什么是JavaScript严格模式
    本篇内容介绍了“什么是JavaScript严格模式”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!JavaS...
    99+
    2024-04-02
  • java中常见的几种单例模式
    这篇文章主要为大家展示了“java中常见的几种单例模式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java中常见的几种单例模式”这篇文章吧。  单例模式:是一种常用的软件设计模式,在它的核心结...
    99+
    2023-06-19
  • JavaScript中常见的几种继承方式
    目录原型继承内存图分析盗用构造函数继承分析组合继承原型链继承寄生式继承寄生组合式继承原型继承 function Parent(name) { this.name = name }...
    99+
    2024-04-02
  • PHP中几种常见的开发模式
    本篇文章给大家带来了关于PHP的相关知识,其中主要介绍了几种常见的开发模式,下面一起来看一下,希望对大家有帮助。设计模式六大原则开放封闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。里氏替换原则:所有引用基类的地方必须能透明...
    99+
    2023-05-14
    php
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作