# debug

back

# 相知

console 对象是由宿主环境提供的,如浏览器和 nodejs,作为全局对象的一个属性,不需要通过构造函数创建,直接使用即可,console 对象的proto指向的是一个空对象,所以 console 对象的方法都挂在对象自身,在 chrome 控制台打印 console 可以看有如下方法或属性:

2021-07-06_134621.gif

console 输出信息的方法都可以接收多个以逗号分隔的参数,打印的时候会在同一行进行显示,不会换行,想要换行的话请使用 console 方法打印多次。

# 想输出不同等级的调试信息,如警告信息或报错信息

调试级别的信息可以使用console.debug方法,控制台默认是不显示的,想要看到的话需要勾上控制台对应的选项:

# 想查看某个 DOM 元素的所有属性

比如说我想看 body 元素的所有属性要怎么看呢:

console.log(document.body); // 这样在控制台打印出的是dom结构,看不到具体是属性
1

那怎么办呢,可以使用 for in 来遍历:

for (let p in document.body) {
  console.log(p, document.body[p]);
}
1
2
3

当然,以上都不是最简单的,最简单的是直接使用console.dir方法

# 有时候 console 写多了,打印出太多信息,无法一眼看

这个可以手动把其他的都给注释掉,只留你本次需要的(这要你说?),当然如果你愿意多敲几行代码的话,也可以使用console.group方法来进行分组显示,使用console.groupEnd方法结束分组,可以多级嵌套:

# 在控制台画条龙吧

// 加载龙的图片
let img = new Image();
img.src = "./龙.jpg";
img.onload = () => {
  draw();
};
// 把图片绘制到canvas里
const draw = () => {
  const canvas = document.getElementById("canvas");
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext("2d");
  ctx.drawImage(img, 0, 0, img.width, img.height);
  // 获取像素数据
  const imgData = ctx.getImageData(0, 0, img.width, img.height).data;
  // 拼接字符
  join(imgData);
};
// 把像素数据拼接成字符
const join = (data) => {
  let gap = 10;
  let str = "";
  for (let h = 0; h < img.height; h += gap) {
    str += "\n";
    for (let w = 0; w < img.width; w += gap) {
      str += " "; // 因为字符的高度普遍都比其宽度大,所以额外添加一个空字符平衡一下,否则最终的图形会感觉被拉高了
      let pos = (h * img.width + w) * 4;
      let r = data[pos];
      let g = data[pos + 1];
      let b = data[pos + 2];
      // rgb转换成yuv格式,根据y(亮度)来判断显示什么字符
      let y = r * 0.299 + g * 0.578 + b * 0.114;
      if (y >= 190) {
        // 浅色
        str += " ";
      } else {
        // 深色
        str += "#";
      }
    }
  }
  console.log(str);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 打印出来的值会变

可以看到旁边都有个叹号,移上去会显示一行提示:This value was evaluated upon first expanding,It may have changed since then.,意思就是这个值计算了一次,但是后面可能是会变化的,所以我们往往会使用:console.log(JSON.stringify(obj))或者深拷贝一下再打印,有没有更简单的方法呢?我们可以给 console 加两个方法,一个叫console.obj,先深拷贝一下再打印,另一个叫console.str,把对象序列化后再打印:

console.obj = function(...args) {
  let newArgs = args.map((item) => {
    if (
      Object.prototype.toString.call(item) === "[object Object]" ||
      Array.isArray(item)
    ) {
      return deepClone(item);
    } else {
      return item;
    }
  });
  console.log(...newArgs);
};

console.str = function(...args) {
  let newArgs = args.map((item) => {
    try {
      let obj = JSON.stringify(item);
      return obj;
    } catch (e) {
      return item;
    }
  });
  console.log(...newArgs);
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 将 CSS 添加到控制台消息

back

// 通过在文字前加上 ‘%c’, 然后在后方写入css设置即可将console。log加上CSS样式

console.log(
  "%c这是示例的文字-Tz",
  "color:pink;font-size:50px;font-weight: 500"
);
console.log("%c这是示例的文字-Tz", "color:red;font-size:20px;font-weight: 600");
console.log(
  "%c这是示例的文字-Tz",
  "color:blue;font-size:12px;font-weight: 700"
);
1
2
3
4
5
6
7
8
9
10
11

# 如何为日志消息中的特定单词涂上颜色

back

// 通过在文字前加上 ‘%c’, 然后在后方写入css设置即可将console.log加上CSS样式
console.log(
  "哪有人就哪有江湖 相持相扶%c--Tz张无忌",
  "background-color:#222;font-size:24px;font-weight: 500;color:#bada55"
);
1
2
3
4
5

# 控制台中的 HTML 元素

back

let zhangwuji = document.getElementsByTagName("body")[0];
console.log(zhangwuji);
1
2

# 灵活使用 console 让 js 调试更简单

back

# log

back

在 console.log 中有很多人们意想不到的功能。虽然大多数人使用console.log(object)来查看对象,但是你也可以使用console.log(object, otherObject, string),它会把它们都整齐地记录下来,偶尔也会很方便。
不仅如此,还有另一种格式化的: console.log(msg, values),这很像 C 或 PHP 中的 sprintf。

console.log("I like %s but I do not like %s.", "Skittles", "pus");
1

会像你预期的那样输出:

> I like Skittles but I do not like pus.
1

常见的占位符 %o(这是字母o,不是0),它接受对象%s接受字符串%d表示小数或整数

另一个有趣的是 %c,这可能与你所想不太相同,它实际上是 CSS 值的占位符。使用%c 占位符时,对应的后面的参数必须是 CSS 语句,用来对输出内容进行 CSS 渲染。常见的输出方式有两种:文字样式、图片输出。

console.log(
  "I am a %cbutton",
  "color: white; background-color: orange; padding: 2px 5px; border-radius: 2px"
);
1
2
3
4

# dir

back

在大多数情况下,console.dir 的函数非常类似于 log,尽管它看起来略有不同。

# warn

back

# table

back

令人惊讶的是,这并不是更为人所知,但是 console.table函数旨在以一种比仅仅转出原始对象数组更整洁的方式显示表格数据。

第二个可选参数是所需列的列表。显然,所有列都是默认值,但我们也可以这样做:

console.table(data, ["id", "price"]);
1

console.table 只能处理最多 1000 行,因此它可能不适合所有数据集。

# assert

back

assert 与 log 是相同的函数,assert 是对输入的表达式进行断言,只有表达式为false时,才输出相应的信息到控制台

示例如下:

const arr=[1,2,3,4];

console.assert(arr.length===5,arr)
VM275:1 Assertion failed: (4) [1, 2, 3, 4]0: 11: 22: 33: 4length: 4__proto__: Array(0)
(anonymous) @ VM275:1

console.assert(arr.length===4,arr)
1
2
3
4
5
6
7

# count

back

另一个具有特殊用途的计数器,count 只是作为一个计数器,或者作为一个命名计数器,可以统计代码被执行的次数

还有一个相关的 console.countReset,可以使用它重置计数器。 此函数记录此特定调用 count()已被调用的次数。该函数带有一个可选参数 label。
如果 label 提供了该函数,则该函数记录该 count()特定调用的次数 label。
如果 label 省略,则函数记录在此特定行 count()上被调用的次数。

for (let i = 0; i < 11; i++) {
  console.count();
}
1
2
3

# trace

back

trace 在简单的数据中很难演示。当您试图在类或库中找出是哪个实际调用者导致了这个问题时,它的优势就显现出来了。

# time

back

console.time 是一个用于跟踪操作时间的专用函数,它是跟踪 JavaScript 执行时间的好方法。

const slowFunction = number => { console.time('slowFunction'); // something slow or complex with the numbers. // Factorials, or whatever.
console.timeEnd('slowFunction');}console.time;

for (i = 0; i < 100000; ++i) { slowFunction(i);}console.timeEnd;
1
2
3
4

# group

back

console.group();
console.log("Dream");
console.groupEnd();
console.group();
console.log("5");
console.log("2");
console.log("1");
console.groupEnd();
console.group();
console.log("1");
console.log("3");
console.log("1");
console.log("4");
console.groupEnd();
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# clear

back

清除控制台和内存——clear();

一些网站可能不喜欢被人调试,只要打开控制台就自动进入调试模式,还是无限 debugger 的那种

setInterval(() => {
  debugger;
}, 1000);
1
2
3