资讯专栏INFORMATION COLUMN

被忽略的console.log

JayChen / 841人阅读

摘要:在旧的中有超出人期望令人惊讶的功能。令人惊讶的是,这并不是更为人所知,但是函数旨在以比抛出原始对象数组更简洁的方式显示表格数据。适用于过大的物体,细节基本无关。这样做会将其称为默认值。最后要指出的是。

除了console.log之外,还有更多方式调试JavaScript来输出值。 看起来很明显我们没有。

人们告诉我,做JavaScript应该使用浏览器的调试器,但这肯定是要看运行环境的。 但是很多时候你只想知道代码的某一部分是执行还是变量是什么,而不会看着断点消失庞大的代码类库中。

尽管如此,虽然我们使用console.log,但是很多人都没有意识到控制台本身除了基本日志之外还有很多其他选项。 适当使用这些功能可以使调试更容易,更快速,更直观。

console.log()

在旧的console.log中有超出人期望令人惊讶的功能。 虽然大多数人将它用作console.log(obj),但您也可以执行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");

将完全按照您的预期输出。

> I like Skittles but I do not like pus.

常见的占位符是%o(这是一个字母o,而不是零),它接受一个对象,%s接受一个字符串,%d是一个十进制或整数。

另一个有趣的是%c, 它实际上是CSS值的占位符。

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

这些值会运行到后面的任何内容上,没有“结束标记”,这有点奇怪。 但你可以将它变得像这样。

它不优雅,也不是特别有用。 当然,这不是一个真正的按钮。

它有用吗?Ehhhhh。

console.dir()

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

向下的小箭头将显示与上面相同的确切对象详细信息,这也可以从console.log版本中看到。 当你看到元素时,事物的分歧更加剧烈,更有趣。

let element = document.getElementById("2x-container");

这是记录输入的输出:

我打开了一些元素。 这清楚地显示了DOM,我们可以浏览它。 但是console.dir(element)为我们提供了惊人的不同输出。

这是一种更加客观的方式来查看元素。 有时候这就是你真正想要的东西,更像是检查元素。

console.warn()

可能是最明显的直接替换log(),你可以用完全相同的方式使用console.warn()。 唯一真正的区别是输出有点黄。 具体来说,输出处于警告级别而不是信息级别,因此浏览器将稍微区别对待它。 这具有使其在杂乱输出中更明显的效果。

但是,有一个更大的优势。 因为输出是警告而不是信息,所以您可以过滤掉所有console.log并仅保留console.warn。 这对于偶尔会在浏览器中输出大量无用废话的偶尔繁琐的应用程序尤其有用。 清除噪音可以让您更轻松地看到输出。

console.table()

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

例如,这是一个数据列表。

const transactions = [{
  id: "7cb1-e041b126-f3b8",
  seller: "WAL0412",
  buyer: "WAL3023",
  price: 203450,
  time: 1539688433
},
{
  id: "1d4c-31f8f14b-1571",
  seller: "WAL0452",
  buyer: "WAL3023",
  price: 348299,
  time: 1539688433
},
{
  id: "b12c-b3adf58f-809f",
  seller: "WAL0012",
  buyer: "WAL2025",
  price: 59240,
  time: 1539688433
}];

如果我们使用console.log来转储上面的内容,我们会得到一些非常无用的输出:

▶ (3) [{…}, {…}, {…}]

小箭头让你点击并打开阵列,当然,但这并不是我们想要的“一目了然”。

虽然console.tabl(data)的输出更有帮助。

可选的第二个参数是您想要的列的列表。 显然默认为所有列,但我们也可以这样做。

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

我们得到这个输出,只显示id和价格。 适用于过大的物体,细节基本无关。 索引列是自动创建的,并且据我所知不可以去掉。

这里要注意的是这是乱序的 - 最右边的列标题上的箭头显示了原因。 我点击该列进行排序。 找到列的最大或最小,或者只是对数据进行不同的查看非常方便。 顺便说一句,该功能与显示部分列无关。 它始终可用。

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

console.assert()

断言有用的函数assert()log() 相同,但仅在第一个参数为false的情况下。 如果第一个参数为真,它什么都不做。

这对于有循环(或几个不同的函数调用)并且只有一个显示特定行为的情况特别有用。 基本上它和这样做是一样的。

if (object.whatever === "value") {
  console.log(object);
}

澄清的是,当我说“相同”时,做起来却是相反的。 所以你需要反转条件。

因此,让我们假设上面的一个值是在时间戳中使用null0,这会搞砸我们的代码格式化日期。

console.assert(tx.timestamp, tx);

当与任何有效的事务对象一起使用时,它只是跳过去。 但是false会触发我们的日志记录,因为时间戳是0null

有时我们想要更复杂的条件。 例如,我们已经看到用户WAL0412的数据存在问题,并且只想显示来自它们的事务。 这是直观的解决方案。

console.assert(tx.buyer === "WAL0412", tx);

这看起来正确,但不起作用。 请记住,条件必须是false...我们要断言,而不是过滤。

console.assert(tx.buyer !== "WAL0412", tx);

这将做我们想要的。 买方不是WAL0412的任何交易在该条件下都是正确的,只留下那些。 或者......不是。

像其中的一些,console.assert()并不总是特别有用。 但在特定情况下它可以是一个优雅的解决方案。

console.count()

另一个使用有用的功能,count只是作为一个计数器,可选择作为一个命名计数器。

for(let i = 0; i < 10000; i++) {
  if(i % 2) {
    console.count("odds");
  }
  if(!(i % 5)) {
    console.count("multiplesOfFive");
  }
  if(isPrime(i)) {
    console.count("prime");
  }
}

这不是有用的代码,有点抽象。 此外,我不打算演示isPrime函数,这是个伪代码。

我们得到的应该基本上是一个列表

odds: 1
odds: 2
prime: 1
odds: 3
multiplesOfFive: 1
prime: 2
odds: 4
prime: 3
odds: 5
multiplesOfFive: 2
...

等等。 这对于您可能只是转储索引的情况很有用,或者您希望保留一个(或多个)运行计数。

您也可以像这样使用console.count(),不带参数。 这样做会将其称为默认值。

如果您愿意,还可以使用相关的console.countReset()来重置计数器。

console.trace()

这很难用简单的数据进行演示。 它擅长的地方在于你试图弄清楚实际调用者导致问题的类或库。

例如,可能有12个不同的组件调用服务,但其中一个组件没有正确设置依赖关系。

export default class CupcakeService {
    
  constructor(dataLib) {
    this.dataLib = dataLib;
    if(typeof dataLib !== "object") {
      console.log(dataLib);
      console.trace();
    }
  }
  ...
}

在这里多带带使用console.log()会告诉我们传入的dataLib是什么,而不是在哪里。 但是,堆栈跟踪将非常清楚地告诉我们问题是Dashboard.js,我们可以看到它是新的CupcakeService(false)并导致错误。

console.time()

用于跟踪操作所用时间的专用函数console.time()是跟踪JavaScript执行所用微时间的更好方法。

function slowFunction(number) {
  var functionTimerStart = new Date().getTime();
  // something slow or complex with the numbers. 
  // Factorials, or whatever.
  var functionTime = new Date().getTime() - functionTimerStart;
  console.log(`Function time: ${ functionTime }`);
}
var start = new Date().getTime();

for (i = 0; i < 100000; ++i) {
  slowFunction(i);
}

var time = new Date().getTime() - start;
console.log(`Execution time: ${ time }`);

这是一种老式的方法。 我还应该指向上面的console.log。 很多人都没有意识到你可以在那里使用模板字符串和插值,但你可以。 很有帮助。

所以让我们使用新方法试试。

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();

我们现在不再需要做任何数学运算或设置临时变量。

console.group()

现在可能是控制台输出中最复杂和最先进的区域。 group让你......好吧,分组。 特别是它可以让你嵌套东西。 它擅长的地方在于显示代码中存在的结构。

// this is the global scope
let number = 1;
console.group("OutsideLoop");
console.log(number);
console.group("Loop");
for (let i = 0; i < 5; i++) {
  number = i + number;
  console.log(number);
}
console.groupEnd();
console.log(number);
console.groupEnd();
console.log("All done now");

这又是一种循环。 你可以在这里看到输出。

虽然不是很有用,但你可能会看到其中一些是如何组合在一起的。

class MyClass {
  constructor(dataAccess) {
    console.group("Constructor");
    console.log("Constructor executed");
    console.assert(typeof dataAccess === "object", 
      "Potentially incorrect dataAccess object");
    this.initializeEvents();
    console.groupEnd();
  }
  initializeEvents() {
    console.group("events");
    console.log("Initialising events");
    console.groupEnd();
  }
}
let myClass = new MyClass(false);

这是很多工作和很多用于调试信息的代码,可能不是那么有用。 但它仍然是一个有趣的想法,您可以看到它可以使您的日志记录更加清晰。

最后要指出的是console.groupCollapsed。 在功能上,这与console.group相同,但块开始关闭。 它没有得到很好的支持,但如果你有一大堆废话,你可能想要默认隐藏它是一个选项。

结论

这里没有太多结论。 所有这些工具都可能有用,如果你可能只需要一点点console.log(pet),但实际上并不需要调试器。

可能最有用的是console.table,但所有其他api也都有自己的作用。 我是console.assert的粉丝,因为我们想调试一些东西,但只能在特定情况下调试。

创建了一个程序员交流微信群,大家进群交流IT技术

如果已过期,可以添加博主微信号15706211347,拉你进群

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99902.html

相关文章

  • 【rxjs5.x】filter操作符

    摘要:操作符防抖动,只有当另一个发射值时,才取源的最新数据进行发射,其他数据取消发射。输出从源数据集的第一项开始进行发射,直到另一个开始发射第一个值时,源停止发射值。 rxjs5.x filter操作符api debounce 防抖动,只有当另一个Observable发射值时,才取源Obervable的最新数据进行发射,其他数据取消发射。 // 每次点击,且当计时器的最新值未被发射时,才从计...

    Forelax 评论0 收藏0
  • Javascript 函数和变量提升

    摘要:同名变量和函数,函数会提升到最前边,变量其次,为什么不那为什么结果不是我们人工执行的呢原因是变量会被忽略,是的是忽略。。。同名变量解析完顺序是这样的忽略同名变量,声明会被提升,后边会忽略。 变量提升和函数提升基本上是面试必问题目 //先从一个面试题说起 console.log(a) if (a) { var a = 1; ...

    王陆宽 评论0 收藏0
  • 关于箭头函数思考

    摘要:关于箭头函数的思考自从有了箭头函数这个灵活的功能,现在写函数都习惯写成箭头函数格式然而如果不理解箭头函数的原理,滥用它也会造成很大的影响。等同于等同于如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用语句返回。 关于箭头函数的思考 自从有了ES6箭头函数这个灵活的功能,现在写函数都习惯写成箭头函数格式 () => {} 然而如果不理解箭头函数的原理,滥用它也会造...

    ytwman 评论0 收藏0
  • 那些忽略 JavaScript 数组方法细节

    摘要:这两个方法的参数是一致的,回调函数和执行回调函数时使用的值,回调函数中的参数也是一致的,分别是数组当前元素当前元素索引和数组本身。 青湛(GitHub/mintsweet) 原文链接 前言 自以为还算一个比较高产的人吧~但是感觉好久都没有写点什么没有营养的东西了,这一篇本来是打算去年年底都要拿出来说一说的,但是年底事情太多了,加上我真的变懒了拖到现在才要把这个准备了好久的标题完善一下...

    jsyzchen 评论0 收藏0
  • JavaScript Number()方法和ParseInt()/ParseFloat()方法转换

    摘要:在项目开发中我们经常会用到转型方法,尤其是这种松散型的语言。其中比较常用的方法就是方法和方法了,下面我们分别对这几种方法的转型机制进行详细地说明。 在项目开发中我们经常会用到转型方法,尤其是JS这种松散型的语言。其中比较常用的方法就是Number()方法和ParseInt()/ParseFloat()方法了,下面我们分别对这几种方法的转型机制进行详细地说明。 Number() 如...

    Simon_Zhou 评论0 收藏0
  • 来一轮带注释demo,彻底搞懂javascript中replace函数

    摘要:对应于上述的,等。匹配到的子字符串在原字符串中的偏移量。插入当前匹配的子串右边的内容。 javascript这门语言一直就像一位带着面纱的美女,总是看不清,摸不透,一直专注服务器端,也从来没有特别重视过,直到最近几年,javascript越来越重要,越来越通用。最近和前端走的比较近,借此机会,好好巩固一下相关知识点。 1.初识replace 在js中有两个replace函数 一个是lo...

    Coding01 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<