`
lihong11
  • 浏览: 456273 次
  • 性别: Icon_minigender_2
  • 来自: 湖南
社区版块
存档分类
最新评论

JS 代码调试经验总结(菜鸟必读)

阅读更多


前言:不知不觉写了很多,希望你能耐心看完这篇文章

 

任何一个编程者都少不了要去调试代码,不管你是高手还是菜鸟,调试程序都是一项必不可少的工作。一般来说调试程序是在编写代码之后或测试期修改Bug 时进行的,往往在调试代码期间更加能够体现出编程者的水平高低以及分析问题的准确度。不少初学者在寻找错误原因时,总是不得要领,花费了大量时间却无法解决一些最终证明是相当简单的Bug。

 

在长期解答 zTree 相关问题时,也的确发现很多的问题其实不算什么问题,仅仅是编程者不会调试造成的,通过自己日常工作观察,这里面有态度问题也有思考问题的方式方法,故总结一下自己经验,以供大家参考(尤其是菜鸟), 对于高手来讲,如果你愿意看完这篇文章,也非常欢迎拍砖和提供建议,我相信这样可以不断让这篇文章充实并完善起来,肯定也可以帮助到更多的朋友。

 

试想一下:出现了某个bug,有人用几分钟就搞定了,有人用了半天或者一天都找不到原因所在。你愿意当前者还是后者呢?想当前者的就请好好看完本篇文章吧。

 

本篇文章主要是帮助大家在调试代码时,如何建立解决问题的思路。所以并不会专门介绍不同浏览器的具体调试方法。(在网上关于 chrome、firefox、ie 等浏览器的具体调试方法已经有很多了,这里就不一一描述啦。)另外,俗话说的好——“js、html 和 css 是一家”,因此在讲述中也会稍带有html 和 css 的内容。

 

一、 遇到错误怎么办?

辛辛苦苦写了一大段代码却无法运行,怎么办?……前两天还正常的代码怎么今天报错了,怎么办?……同样的代码在这个页面正常怎么到了另一页面就出问题了,怎么办?……这些情况你都遇到过吗?是否被错误搞得焦头烂额、心情烦躁?(“不管路途有多么遥远,有多少艰难险阻,都不可能阻挡我前进的步伐!”——唐师傅)

 

1、 调整心态

出现问题很正常,其实不出问题反倒不太正常。所以当发现问题的时候我们需要冷静。不要在乎身后站着的是谁,不要在乎距离上线时间还有几个小时,让自己平静下来,深呼一口气——来吧,不就是个小问题嘛。所有的Bug都在我的掌控之中!

禁忌:出了问题就找人帮忙,这样会导致经常打扰别人,而且也不利于自己的技能提升。只有当自己经过一番努力后,的确找不到解决办法时再去寻求帮助。而且提出问题时,也要尽量将问题描述清楚。

 

2、 寻找特征

解决错误的前提是要发现错误,发现错误的前提嘛…当然是要去“寻找”喽!对于简单的报错信息完全可以利用调试工具的提示:xxxx行出现什么什么错误。如果这则信息100%有效,那么你就不需要再看这篇文章了。

我们遇见的错误表象一般分为以下几种

 

  • 直接报告 js 语法错误

 

这种一般最容易解决,不需要我来废话了……

 

  • js 报错,但报错地点不是出问题的根源

 

这种情况大部分可以解决,但有时候完全不知道是从哪里引用过来的,这种时候会相当的头疼。

 

  • js 无报错,但功能无效

 

这种情况更糟糕,完全没有头绪了……那我告诉你,往往这种时候最终解决错误的方法更容易。

根据特征,往往能够快速定位错误的大概位置,便于进一步查找问题。

 

3、 怀疑一切

当有人告诉你代码有问题时,我们的第一反应经常是:“不可能!”,“你是不是看错了?”,“我刚才运行还好好地呢!”如果你有以上想法,那么需要注意喽!这些想法很危险,如果想解决问题,那么我们就要去怀疑任何有可能的事情,要以特征为主,不要主观断定哪些地方肯定不会出错。

 

二、 如何让错误现出原形?

前面主要是为了让我们能有一个良好的心态来处理问题,情绪保持冷静可以让我们的思维更加敏捷,抓住特征可以让我们更快的找到线索,怀疑一切可以让我们有更多的思路去发现错误。(“不把妖孽打得显出原形,就别想翻过这座山!”——猴哥)

 

1、 化繁为简

临床表现:莫名其妙的报错,不方便调试,单纯看代码无法解释出错原因。

主要病因:js脚本冲突、Css冲突、DOM的ID冲突、DOM标签缺失等多种由于冲突产生的bug根源

排查方法:熟练使用 Delete / Backspace 键,对代码不断进行区域删除,直到症状消失,最后一次删除的区域很可能就是导致错误的根源。进一步查找根源可以在目标区域使用更小单位的区域定义反复使用此方法。

注意:

 

  • 对于 js 代码建议分别以类库  功能  行 为单位进行删除测试
  • 对于 HTML 代码建议按照页面结构先删除最内部的 tag,由内及外,这样可以迅速发现由于 tag 缺失造成的错误,同时也能保证每次删除的都是整段的代码,避免由于删除产生新的错误。
  • 对于 css 代码建议按照css文件  定义的class系列  行 为单位批量进行删除测试

 

忌:对于确认与相关功能有关的部分不要随便删除。

副作用:使用此方法也可以很好的确认错误原因是js造成的还是css造成的。

 

2、 顺藤摸瓜

临床表现:错误信息较准确,能够按照提示的错误逐层跟踪,使用“化繁为简”能够基本定位的错误类型

主要病因:基本语法错误、逻辑错误、不严谨(最常见的有:数组下标越界,null空指针导致的对象找不到,undefined未初始化,NaN数字计算错误等)

排查方法:利用浏览器的调试工具(F12是个很好的功能键):跟踪代码;利用console.log 输出监控对象(IE无效);利用 alert监控(最无奈的方法,用于极端情况);把调试代码加载报错命令行的前面,一般都会有奇效!

注意:

 

  • 对于无js 报错的情况,直接调试无效功能的代码即可。有时候会发现之所以功能无效的原因居然是没有调用该代码!(是不是很可笑?我承认我犯过这种错误。)
  • 逻辑错误往往不太容易想清楚,这时候可以适当结合“化繁为简”的思路进行调试。
  • 当你使用的是类似于 jQuery 这种js库时,如果报错信息处于js库内,首先要更换为未压缩的js代码进行调试,然后分析是自己的哪段代码会调用相关功能。

 

忌:钻牛角尖!当按照此方法仍无法找到错误根源时,说明这并不是一个准确的错误信息,肯定有其他潜在的因素在产生错误。立刻更改切入点,不要在一个地方长时间浪费时间。(这种时候,可以参考下一个方法:“反复对照”)

 

3、 反复对照

临床表现: 应用普通方法很难定位错误,前两种方法怎么用都还是找不到头绪。

主要病因: 逻辑复杂、功能互相绑定难以剥离、页面对象内容复杂、有的页面正常有的页面不正常、兼容问题等

排查方法: 对付这种复杂的麻烦,排查方法也会很繁琐,但并不是什么特别高深的技术,只是需要多做一些体力活儿而已。

 

  • 方法一:检查可疑的代码,细化功能点,每次只修改一个地方,修改一次就测试一次,直到发现导致错误的关键代码。
  • 方法二:制作最简单的Demo 只实现需要的功能,当功能正常后,与出错的正式代码进行比较(比较中可以适当使用方法一)
  • 方法三:以正常功能(或出错)的代码为原型,修改一个地方就生成一个测试的备份,每个测试的案例都只有一处与原始代码不同,编上号码,在特殊环境下逐一测试,检查导致错误的根源(我曾经用这个方法解决了韩文系统下IE8加载公司内部flash 不能正常发声的bug)

 

注意:

 

  • 使用此法一定要有耐心
  • 此方法技术含量低,任何人都可以快速掌握,解决某些疑难杂症基本上可以说是药到病除!

 

忌: 急躁、马虎

 

4、 积累经验

临床表现:部分浏览器报错、事件响应异常、js操作DOM无效、PC 和 触屏系统功能不一致等

主要病因:各种兼容问题

排查方法:对于某些有明显特征的报错要熟记于胸,看到这些情况能立刻想到应该是哪些原因导致的。(最明显的例子:Json对象多了一个逗号的情况,只有ie报错)

注意:

 

  • 有个很基础的问题,但有很多初学者出错——没有搞清楚页面 html、css、js 的加载顺序,导致js 操作失败。(去Google 或 Baidu 搜索:“html css js 加载顺序”)
  • 日常工作要细心,勤观察。认真对待每一次查找错误的工作,对于部分非常特殊的情况可以记下来。
  • 熟练利用 Google、Baidu 等搜索引擎,有时候自己第一次遇到的情况,别人早都知道如何解决了。

 

忌:粗心大意、不求甚解

 

5、 细节决定成败

以上四种查找错误的方法全部都依赖于一个核心——细节!细节往往比你的技术水平更重要。说一句夸张点儿的话,能有多少那么高深的技术等着你去做?好好把自己手上的工作认真完成吧!但请记住了,当你重视细节以后,你距离去做高深技术的机会应该也就不远了。

 

三、 如何修正错误?

老程序员们应该已经深有体会,改Bug 最头疼的还是找错,一旦找到错误后,真正解决问题可能真的是只有几分钟。下面针对一些常见的错误原因与修改思路总结一下:

 

1、 基本语法、语言基础

逗号、分号、双引号、单引号 以及 各种括号 估计都曾导致过你的代码错误吧?这些东西记牢,必须知道什么时候应该使用什么,不要为了简化代码而精简这些符号。

例如:if / for 等语句后面的 { } 最好还是带上吧。

补充,对于js中的Number 数字的范围希望大家有一定的了解,因为这个范围肯定和后台语言中的Long不一样的。(已经有不止一个朋友跟我说 zTree 会自动修改节点的id,当我看到案例后,原来是数字溢出了!)

 

2、 条件严谨

对 Array 或者操作对象属性时,尽可能让条件判断语句写的完整、全面一些。

例如:判断 a.abc 的时候,最好别忘了判断 a 是否存在;或者操作Array时先判断一下Array 是否存在,要操作的下标是否越界等。

 

3、 注意兼容(css & js)

警惕部分浏览器不一致或者出错的情况,很多情况都是兼容造成的。如果自己经验不够,直接去Google 或者 Baidu。慢慢的自己经常接触到的一些兼容问题就会牢记下来了。

补充,有时候要注意页头 W3C的定义,曾经有朋友问我 zTree 异常的问题,最终发现是 W3C只写了一半。

 

4、 逻辑陷阱

条件过于复杂;循环、判断反复嵌套都是容易导致逻辑陷阱的因素。遇到这种情况,如果自己实在无法解决那么请个身边的高手来吧,让他帮你讲解一下。我相信,除了那些有点儿自闭的人来说,别人都会愿意帮助你解决问题的(前提是你自己别太遭人恨了,呵呵)

补充:多去看看有关 重构 的技术书籍!会让你提高很多的。

 

5、 异步加载

其实异步加载出现的问题往往属于逻辑陷阱,但我必须要提出来专门讲述,因为在这上面犯错的人太多了!!!!这里专门详细讲述一遍处理方法:

 

  • 对于异步加载出现了异常,请按照以下流程进行逐一排查:

1)页面是否有报错,是否执行到 ajax 部分的代码?(如果正常请看下一条)

 

2)用浏览器的调试工具监控网络,ajax 加载的url 地址是否正确?(如果正常请看下一条)

 

3)用浏览器的调试工具监控网络,传递给url 的参数是否正确?(如果正常请看下一条)

 

4)用浏览器的调试工具监控网络,从url 返回的数据是否正确?(如果正常请看下一条)

 

5)在 ajax 的success中编写调试代码,调试异步加载后的处理方法是否正确

如果以上几步都正常,那么我可以告诉你异步加载本身是一切正常的,还有错怎么办?继续往下看

 

  • 当异步加载确定正常后,就需要考虑另一个重要问题,也就是我在上一篇文章《这些年我们爱犯的弱智错误(菜鸟必看)》中专门讲述的易犯的错误——异步加载的疏忽

1)千万不要在执行了 ajax 之后立刻去执行应该在异步加载完成之后再运行的代码。因为你执行这段代码的时候,ajax根本没有完成呢。(最明显的现象:运行时时好时坏,但如果我加入了alert 会发现每次都正常了)

这种情况,请将你的代码转移到 ajax的 success 或 error 里面去执行

 

2)当你设置了某些特殊开关时,一定不要忘了在 ajax 的error 里面进行重置,否则很可能因为一次网络异常,就会造成你的页面js 功能失效。这种错误常常是地雷级别的,很难被发现。

 

6、 神奇的setTimeout

对于移动设备 或者 某些特殊情况,可以适当考虑使用 setTimeout 来解决问题。

我遇到比较特例的情况:有两个js的事件因为不同的功能在同时对同一个DOM操作时会导致IE8崩溃,显然这是IE的bug,但我无法去要求微软做什么…最终使用 setTimeout 让其中一个功能延迟100-200毫秒再执行,轻松搞定!

 

7、 别在一棵树上吊死

做前端的人都很郁闷要适配n多的浏览器,往往会遇到一些自己无法解决的问题(因为是浏览器bug 造成的),遇到这种情况怎么办?一般来说寻找一下有没有 hacker的方法,如果没有,那么就换一种思路,看看是否可以有其他方案来实现类似的功能。如果各种努力都做了…还有人不满意的话,那么告诉他浏览器的bug,让项目管理者来决定到底如何处理吧——这种情况死而无憾了!

 

 

分享到:
评论

相关推荐

    神奇宝贝(PokemonGo)基于Jetpack+MVVM+Repository设计模式+Data.zip

    神奇宝贝(PokemonGo)基于Jetpack+MVVM+Repository设计模式+Data

    用于试用 Dev Containers 的 Python 示例项目.zip

    用于试用 Dev Containers 的 Python 示例项目试用开发容器Python开发容器是一个具有明确定义的工具/运行时堆栈及其先决条件的运行容器。您可以使用GitHub Codespaces或Visual Studio Code Dev Containers试用开发容器。这是一个示例项目,您可以通过几个简单的步骤尝试任一选项。我们还有各种其他vscode-remote-try-*示例项目。注意如果您已经有代码空间或开发容器,则可以跳至“要尝试的事情”部分。设置开发容器GitHub Codespaces请按照以下步骤在 Codespace 中打开此示例单击代码下拉菜单。单击Codespaces选项卡。单击主屏幕上的“创建代码空间”。有关创建代码空间的更多信息,请访问GitHub 文档。VS Code 开发容器如果您已安装 VS Code 和 Docker,则可以单击上方或此处的徽章开始使用。单击这些链接将导致 VS Code 根据需要自动安装 Dev Containers 扩展,将源代码克隆到容器卷中,并启动开发容器以供使用。按

    springboot vue3前后端分离.zip

    springboot vue3前后端分离

    数学建模-神经网络算法 lecture 11 线性随机系统辨识示例 共9页.pptx

    数学建模-神经网络算法 lecture 11 线性随机系统辨识示例 共9页.pptx

    优质粳稻生产技术规程.docx

    优质粳稻生产技术规程.docx

    所有算法均在 Python 3 中实现,是 hacktoberfest2020 的一个项目 - 没有针对 hacktoberfest 2021 的问题或 PR.zip

    算法 - Python 目录灵感与动力贡献指南从这里开始所有算法均用 Python 3 实现(用于教育)这些实现仅用于学习目的。如果您想贡献更有效的解决方案,请随时打开问题并提交您的解决方案。灵感你可以在LeetCode 算法中寻找要实现的算法若要贡献,请确保算法尚未提交!请确保在您的 PR 中添加问题编号。贡献指南文件夹和文件请确保你的文件位于 -Folder 中LeetCode,并且命名如下 0001_TwoSum.py-> LeetCode 问题的 4 位数字、下划线、LeetCodeName开放问题当您打开问题时,请确保问题尚未实现(查看代码/Leetcode 以获取问题编号)。现有问题打开的问题将被关闭,并且对此问题的 PR 被标记为垃圾邮件 。打开问题的贡献者将被优先分配到该问题。如果大约 7 天内没有 PR,则问题将分配给另一个贡献者。拉取请求只有与问题相结合并符合命名约定(参见文件夹和文件)的 Pull 请求才会被合并!如果 PR 中没有加入问题,您的 PR 将被标记为垃圾邮件并关闭。如果您的代码未通

    用于接收和交互来自 Slack 的 RTM API 的事件的框架.zip

    用于接收和交互来自 Slack 的 RTM API 的事件的框架python-rtmbot此项目不再处于积极开发阶段。如果您刚刚开始,我们建议您先查看Python SDK。如果您一直在使用此项目,我们只会解决关键问题(例如安全问题),但我们建议您计划迁移到 Python SDK。您仍然可以提交问题并向我们寻求帮助! 如果您有兴趣在未来维护此软件包,请联系我们 一个用 Python 编写的 Slack 机器人,通过 RTM API 连接。Python-rtmbot 是一个机器人引擎。任何了解Slack API和 Python的人都应该熟悉插件架构。配置文件格式为 YAML。该项目目前处于 1.0 之前的版本。因此,您应该计划不时进行重大更改。对于任何重大更改,我们将在 1.0 之前的版本中调整次要版本。(例如 0.2.4 -> 0.3.0 意味着重大更改)。如果稳定性很重要,您可能希望锁定特定的次要版本)与 webhook 的一些区别不需要网络服务器来接收消息可以回复用户的直接消息以 Slack 用户(或机器人)身份登录机器人用户必须被邀请加入频道

    基于django的音乐推荐系统.zip

    基于django的音乐推荐系统.zip

    北京理工大学<Python机器学习应用>超详细学习笔记和代码注释(未完待续).zip

    北京理工大学<Python机器学习应用>超详细学习笔记和代码注释(未完待续)

    kernel-5.15-rc7.zip

    kernel-5.15-rc7.zip

    神经网络-DenseNet网络结构

    神经网络-DenseNet网络结构

    rbac组件(基于角色的权限控制).zip

    rbac组件(基于角色的权限控制)

    C++ Vigenère 密码(解密代码)

    C++ Vigenère 密码(解密代码)

    数学建模培训资料 数学建模实战题目真题答案解析解题过程&论文报告 杭州消防设置-对杭州市消防局设置的研究 共8页.pdf

    数学建模培训资料 数学建模实战题目真题答案解析解题过程&论文报告 杭州消防设置-对杭州市消防局设置的研究 共8页.pdf

    老年用品产品推广目录分类表.docx

    老年用品产品推广目录分类表.docx

    毕设源码-基于Python的期货程序化交易系统的设计与实现_jhypi-期末大作业+说明文档.rar

    本项目是基于Python的期货程序化交易系统的设计与实现,旨在为计算机相关专业学生提供一个实践性强、贴近实际应用场景的项目案例。通过这一项目,学生们能够深入了解程序化交易的基本原理和实现方法,同时锻炼自身的编程技能、数据分析能力以及金融市场的洞察力。 项目的主要功能包括:自动收集和处理市场数据、基于预设策略进行交易决策、实时执行交易指令、监控交易风险以及生成详细的交易报告。系统采用模块化设计,主要包括数据采集模块、策略执行模块、交易执行模块和风险管理模块,各个模块之间通过明确的接口进行交互。项目采用的编程语言为Python,利用其强大的数据处理库和机器学习库,保证了系统的灵活性和扩展性。开发这一项目的目的是让学生们在实践中学习和掌握程序化交易的核心技术,提升其在金融科技领域的就业竞争力。

    基于java的校园失物招领平台设计与实现.docx

    基于java的校园失物招领平台设计与实现.docx

    Javascript Ninja 课程.zip

    Javascript Ninja 课程JavaScript Ninja 课程Inscreva-se agora mesmo e ganhe 10% de desconto!Como tirar dúvidas sobre 或 conteúdo do curso访问问题页面Pesquise nas发出abertas e fechadas, se a mesma dúvida já foi postadaSe não foi, crie uma nova issues , coloque um titulo que tenha a ver com a sua dúvida, e descreva-a com o maior nível detalhes possíveis, para que possamos te ajudar:)摘要Veja o sumário completo do curso aqui。赞同!:D

    通过示例在 Python 中解释 SOLID 原则 .zip

    solid.python通过示例在 Python 中解释SOLID 原则。单一职责原则开放/封闭原则里氏替换原则接口隔离原则依赖倒置原则

    公交信息在线查询系统 微信小程序+SSM毕业设计 源码+数据库+论文+启动教程.zip

    公交信息在线查询系统 微信小程序+SSM毕业设计 源码+数据库+论文+启动教程 项目启动教程:https://www.bilibili.com/video/BV1BfB2YYEnS

Global site tag (gtag.js) - Google Analytics