除了console.log以外,还有更多方式调试JavaScript来输出值。 看起来很明显咱们没有。程序员
人们告诉我,作JavaScript应该使用浏览器的调试器,但这确定是要看运行环境的。 可是不少时候你只想知道代码的某一部分是执行仍是变量是什么,而不会看着断点消失庞大的代码类库中。api
尽管如此,虽然咱们使用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');
将彻底按照您的预期输出。ide
> 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');
这些值会运行到后面的任何内容上,没有“结束标记”,这有点奇怪。 但你能够将它变得像这样。oop
它不优雅,也不是特别有用。 固然,这不是一个真正的按钮。this
它有用吗?Ehhhhh。
在大多数状况下,console.dir()
函数很是相似于log()
,尽管它看起来有点不一样。
向下的小箭头将显示与上面相同的确切对象详细信息,这也能够从console.log
版本中看到。 当你看到元素时,事物的分歧更加重烈,更有趣。
let element = document.getElementById('2x-container');
这是记录输入的输出:
我打开了一些元素。 这清楚地显示了DOM,咱们能够浏览它。 可是console.dir(element)为咱们提供了惊人的不一样输出。
这是一种更加客观的方式来查看元素。 有时候这就是你真正想要的东西,更像是检查元素。
多是最明显的直接替换log()
,你能够用彻底相同的方式使用console.warn()
。 惟一真正的区别是输出有点黄。 具体来讲,输出处于警告级别而不是信息级别,所以浏览器将稍微区别对待它。 这具备使其在杂乱输出中更明显的效果。
可是,有一个更大的优点。 由于输出是警告而不是信息,因此您能够过滤掉全部console.log
并仅保留console.warn
。 这对于偶尔会在浏览器中输出大量无用废话的偶尔繁琐的应用程序尤为有用。 清除噪音可让您更轻松地看到输出。
使人惊讶的是,这并非更为人所知,可是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行,所以可能不适合全部数据集。
断言有用的函数assert()
与log()
相同,但仅在第一个参数为false的状况下。 若是第一个参数为真,它什么都不作。
这对于有循环(或几个不一样的函数调用)而且只有一个显示特定行为的状况特别有用。 基本上它和这样作是同样的。
if (object.whatever === 'value') { console.log(object); }
澄清的是,当我说“相同”时,作起来倒是相反的。 因此你须要反转条件。
所以,让咱们假设上面的一个值是在时间戳中使用null
或0
,这会搞砸咱们的代码格式化日期。
console.assert(tx.timestamp, tx);
当与任何有效的事务对象一块儿使用时,它只是跳过去。 可是false
会触发咱们的日志记录,由于时间戳是0
或null
。
有时咱们想要更复杂的条件。 例如,咱们已经看到用户WAL0412的数据存在问题,而且只想显示来自它们的事务。 这是直观的解决方案。
console.assert(tx.buyer === 'WAL0412', tx);
这看起来正确,但不起做用。 请记住,条件必须是false...咱们要断言,而不是过滤。
console.assert(tx.buyer !== 'WAL0412', tx);
这将作咱们想要的。 买方不是WAL0412的任何交易在该条件下都是正确的,只留下那些。 或者......不是。
像其中的一些,console.assert()
并不老是特别有用。 但在特定状况下它能够是一个优雅的解决方案。
另外一个使用有用的功能,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()
来重置计数器。
这很难用简单的数据进行演示。 它擅长的地方在于你试图弄清楚实际调用者致使问题的类或库。
例如,可能有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(
)是跟踪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();
咱们如今再也不须要作任何数学运算或设置临时变量。
如今多是控制台输出中最复杂和最早进的区域。 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,拉你进群