S是解释型语言,是逐条语句解释执行的,如果错误发生在某个语句块,此语句块以前的语句一般都可以正常执行。这不同于C等编译型语言。
代码调试的重点在于找到错误发生点,然后才能有的放矢。
通常可以使用警告框来提示变量信息。
alert(document.body.innerHTML);
当警告框弹出时,用户将需要单击“确定”来继续。
<div id="demo">
<script>
var arr=[1,2,3,4,5]
document.write(arr[2] + ' ') //3
</script>
</div>
需要注意的是是,以下写法会替换整个页面的内容:
<button type="button" onclick="document.write(5 + 6)">试一试</button>
即使是函数调用也是如此。
document.getElementById("demo").innerHTML =""
<h1>JavaScript Array.filter()</h1>
<p>使用通过测试的所有数组元素创建一个新数组。</p>
<p id="demo"></p> //45,25
<script>
var numbers = [45, 4, 9, 16, 25];
var over18 = numbers.filter(myFunction);
document.getElementById("demo").innerHTML = over18;
function myFunction(value, index, array) {
return value > 18;
}
</script>
JS的运行环境是浏览器,由浏览器引擎解释执行JS代码,一般来说,浏览器也提供调试器,如chrome按F12即可调出高试器:
<!DOCTYPE html>
<html>
<body>
<h4>我的第一张网页</h4>
<p>使用F12在浏览器(Chrome、IE、Firefox)中激活调试,然后在调试器菜单中选择“控制台”。</p>
<script>
a = 5;
b = 6;
c = a + b;
console.log(c);
</script>
</body>
</html>
如果您的浏览器支持调试,那么您可以使用 console.log() 在调试窗口中显示 JavaScript 的值:
内置的调试器可打开或关闭,强制将错误报告给用户。
通过调试器,您也可以设置断点(代码执行被中断的位置),并在代码执行时检查变量。
<p id="demo"></p>
<script>
try {
adddlert("欢迎您,亲爱的用户!");
}
catch(err) {
demo.innerHTML = err.message; //adddlert is not defined
}
</script>
JavaScript 实际上会创建带有两个属性的 Error 对象:name 和 message。
name 设置或返回错误名。
message 设置或返回错误消息(一条字符串)。
debugger停止执行 JavaScript,并调用调试函数(如果可用)。
可以注释掉一些可疑代码来确定错误发生点。
或者考虑逐步增加代码的方法,逐步验证,以避免错误。
8.1 意外使用赋值运算符
如果程序员在 if 语句中意外使用赋值运算符(=)而不是比较运算符(===),JavaScript 程序可能会产生一些无法预料的结果。
8.2 令人困惑的加法和级联
加法用于加数值。
级联(Concatenation)用于加字符串。
在 JavaScript 中,这两种运算均使用相同的 + 运算符。
正因如此,将数字作为数值相加,与将数字作为字符串相加,将产生不同的结果:
var x = 10 + 5; // x 中的结果是 15
var x = 10 + "5"; // x 中的结果是 "105"
而加法以外的其它算法运算符可以将字符串进行自动类型转换。
10-"5" // 5
8.3 令人误解的浮点数
JavaScript 中的数字均保存为 64 位的浮点数(Floats),符合IEEE754的标准。
所有编程语言,包括 JavaScript,都存在处理浮点值的困难:
var x = 0.1;
var y = 0.2;
var z = x + y // z=0.30000000000000004
8.4 错位的分号
因为一个错误的分号,此代码块无论 x 的值如何都会执行:
if (x == 19);
{
// code block
}
在一行的结尾自动关闭语句是默认的 JavaScript 行为。
在 JavaScript 中,用分号来关闭(结束)语句是可选的。
8.5 对象使用命名索引
在 JavaScript 中,数组使用数字索引。
在 JavaScript 中,对象使用命名索引。
如果您使用命名索引,那么在访问数组时,JavaScript 会将数组重新定义为标准对象。
<p id="demo"></p>
<script>
var person = [];
person["firstName"] = "Bill";
person["lastName"] = "Gates";
person["age"] = 46;
var x = person.length; // person.length 将返回 0
var y = person[0]; // person[0] 将返回 undefined
y=person["age"]; //ok
y=person.age;//ok
document.getElementById("demo").innerHTML = y
</script>
8.6 Undefined 不是 Null
Undefined 的类型是 Undefined,Null的类型是Object。
JavaScript 对象、变量、属性和方法可以是未定义的。
此外,空的 JavaScript 对象的值可以为 null。
在测试非 null 之前,必须先测试未定义:
if (typeof myObj !== "undefined" && myObj !== null)
8.7 JS没有块作用域(与C语言不同)
在 ES2015 之前,JavaScript 只有两种类型的作用域:全局作用域和函数作用域。
<!DOCTYPE html>
<html>
<body>
<h2>JavaScript</h2>
<p>JavaScript不会为每个代码块创建新的作用域。</p>
<p>此代码将显示 i(10)的值,即使在 for 循环块之外:</p>
<p id="demo"></p>
<script>
for (var i = 0; i < 10; i++) {
// some code
}
document.getElementById("demo").innerHTML = i; //10
</script>
</body>
</html>
ES2015 引入了两个重要的 JavaScript 新关键词:let 和 const。
这两个关键字在 JavaScript 中提供了块作用域(Block Scope)变量(和常量)。
for (let i = 0; i < 10; i++) {
// some code
}
document.getElementById("demo").innerHTML = i; //不能访问
-End-
JavaScript中调试任何内容的最简单方法之一是使用日志记录console.log。但是控制台提供了许多其他方法可以帮助您更好地进行调试。
先看一个简单的示例,我们经常会使用打印一个对象的方式来调试这个对象的值,如下
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>JS</title> </head> <body> <script> const foo = { id: 1, verified: true, color: "蓝色" }; const bar = { id: 2, verified: false, color: "红色" }; console.log(foo); console.log(bar); </script> </body> </html>
这段代码我们在进入页面后,打印了两个对象,这样有一个很明显的问题就是我们并不知道变量名,当然,你也可以在打印的时候带上变量名,就像这样
<script> const foo = { id: 1, verified: true, color: "蓝色" }; const bar = { id: 2, verified: false, color: "红色" }; console.log("foo", foo); console.log("bar", bar); console.log({ foo, bar }); </script>
这两种方式都可以,要么自己打印出来,要么组合成一个对象,而且大多数情况下我们也有可能就是这么干的,看下控制台
缺点就是我们需要展开对象才能看到对象属性的值。
除了console.log()我们还可以使用console.table(),我们来尝试下
<script> const foo = { id: 1, verified: true, color: "蓝色" }; const bar = { id: 2, verified: false, color: "红色" }; console.table({ foo, bar }); </script>
浏览器截图如图,控制台输出了一个表格和一个组合对象,这样要比单纯的console.log()直观的多
如果你想要将相关详细信息分组或嵌套在一起或者在函数中包含一些日志语句并且希望能够清楚地看到与每个语句对应的范围时,可以使用console.group(),示例代码如下
<script> console.group("用户详情:"); console.log("姓名: 孙悟空"); console.log("职业: 软件开发工程师"); console.group("住址"); console.log("街道: 123 大唐路"); console.log("城市: 大唐"); console.groupEnd(); </script>
浏览器截图如下
相当的直观,虽然这样的场景可能我们遇到的并不多,如果你想默认折叠这段信息,你可以使用groupCollapsed替代group。
根据具体情况,为了确保控制台更具可读性,可以使用console.warn()或console.error() 添加日志。console.info()在某些浏览器中还会显示“i”图标;
<script> console.error("这是一error"); console.warn("这是一个warn"); console.info("这是一个info"); </script>
设置可以添加自定义样式更进一步。可以使用%c指令将样式添加到任何日志语句。这可以通过保持约定来区分API调用,用户事件等。下面是一个例子:
<script> console.log( "%c Auth ", "color: white; background-color: #2274A5", "登录也渲染了" ); console.log( "%c GraphQL ", "color: white; background-color: #95B46A", "获取用户详情" ); console.log( "%c Error ", "color: white; background-color: #D33F49", "获取用户信息出错" ); </script>
调试JavaScript程序时,有时需要打印函数调用的栈信息,这可以通过使用console.trace()来实现,示例如下:
<script> function doTask() { doSubTask(1000, 10000); } function doSubTask(countX, countY) { for (var i = 0; i < countX; i++) { for (var j = 0; j < countY; j++) {} } console.trace(); } doTask(); </script>
如同其他语言的一些定时函数,我们可以使用console.time()来监视一段代码执行的时间
<script> let i = 0; console.time("While"); while (i < 1000000) { i++; } console.timeEnd("While"); console.time("For"); for (i = 0; i < 1000000; i++) { // For Loop } console.timeEnd("For"); </script>
本文总结了一些在Web开发中常用的调试技巧,能让我们在开发时如鱼得水,希望对你有所帮助!
在我们的日常开发中我们常常会遇到JavaScript的调试问题,而我们解决问题的传统解决方案就是使用大量的console.log或者console对象的其他方法,这会给我们带来很多不便,特别是遇到复杂问题的时候,可能会出现大量的console.log,当排查出问题之后我们又不得不在回头清除掉这些调试信息,这样大大降低了我们的工作效率。所以,我们有必要寻找更好的方案来解决JavaScript的调试问题,无疑,Chrome的调试工具Chrome DevTools给我们带来了调试的遍历,下面我们一步步来学习一遍在DevTools中调试的基本工作流程!
我们通过一节简单的案例来模拟一下,本案例来源于官网的调试Demo,其中index.html代码如下
然后是index.js
代码的本意是要做一个简单的加法,但是我们运行看下结果:
显然执行结果是错误的,结果应该是33,我们假设这就是我们在开发中遇到的问题
从左依次是
通常我们会在这写console.log,打完断点我们在填入两个数字提交
我们的代码在断点处暂停了,很直观的能看到我们需要看的变量值,简单来说就是断点可以快速方便的查看你想看的值,有时候我想单步调试代码,直接F10就行了,想进入到函数中按F11,我们调试到这和我们猜想的一样,由于是字符串那么+号就意味着连接,也就造成了错误的结果。
我认为这是最值得赞一波的功能,因为我们可以直接在控制台输入变量或者表达式或者执行一个函数,我们打开console标签,输入以下内容,前提是我们在之前那个地方打了断点
我们可以执行我们需要执行的函数和表达式,然后也正确的看到了结果,知道的人可能觉得没什么,但是不知道的人可能觉得这个功能非常Nice,或者你可以直接修改代码保存后在执行,同样知道了结果,而不必再到编辑器修改,调试正确后直接复制过去即可
本文就是想通过简单的案例介绍来改变下我们传统的js调试方式,目的就是为了提升工作效率,当然也有很多其它方式调试javascript,比如WebStorm,VSCode安装Debug for Chrome,只是我觉得这种方式最直接,同时也最简单,虽然是小技巧,但是也得知道不是,希望对大家能够有所帮助!
*请认真填写需求信息,我们会在24小时内与您取得联系。