【Debug】 你所不知道的各种前端Debug技巧系列 Console - Utilities Function---第8天

  • 时间:
  • 浏览:
  • 来源:互联网

除了可以在JavaScript 执行的Console API 外,Console 还提供了一些Debug 专用的Function,每一个都身怀绝技。

阅读本篇文章时建议搭配Demo页面Console - Utilities,效果更佳。

Console Utility Functions

还记得笔者第一次看到这些Function时特别兴奋,直接写在自己的程式码中,想当然是跳出了各种Uncaught ReferenceError: xxx is not defined。

$_

会 储 存 的 执 行 结 果 , 在 C o n s o l e 测 试 J a v a S c r i p t 行 为 的 时 候 通 常 都 会 逐 步 确 认 , 正 是 使 用 _会储存的执行结果,在Console测试JavaScript行为的时候通常都会逐步确认,正是使用 ConsoleJavaScript使_ 的好时机:
在这里插入图片描述
用到很多不能Chain的Function时能利用$_来避免游标来回修改:

在这里插入图片描述
顺带一提,未来也有可能出现Pipeline operator来做到任意Function chaining ,提升可读性或避免需要修改内建Prototypes。

let a;
a = 1
  |> ((n) => add(n, 5))
  |> double;

console.log(a); // 12

$, $$

$(selector[, element]), $$(selector[, element])

和 和 $分别就是document.querySelector和document.querySelectorAll的缩写,来源就是大家熟知的JQuery。

第二个参数可以放入起始的元素。搭配$0就可以先Inspect一个元素,再从它开始搜寻。

$('.btn', $0)

笔者常用$$来快速测试一些行为,例如印出个人GitHub页面的所有Repository名称:

在这里插入图片描述
不过如果已经引入套件如JQuery为$的话,还是会正常执行JQuery。

debug

debug(function)

参数为一个Function,只要执行到该Function就会触发Debugger,可以用undebug(fn)来取消:

function a() {
  console.log(1);
}

debug(a);
// undebug(a);

其效果相当于:

function a() {
  console.log(1);
}
a = (function() {
  const origin = a;
  return function() {
    debugger;
    origin();
  }
})();

关于断点(Breakpoints)的使用,会在之后关于Sources 的文章有更详细的解释。

monitor

monitor(function)

用法和debug很像,monitor的Function被执行时会印出Function名称和参数,
在这里插入图片描述
可用unmonitor(function)来停止,不过无法用在Arrow function,需要监听Arrow function的执行就只能手动覆写了。

monitorEvents
monitorEvents(element[, eventType])

可以在监听并印出元素的特定事件,比较特别的是除了能监听单一事件,还能监听事件类型,例如印出window的点击事件和所有touch类别的事件:
在这里插入图片描述
效果和以下JavaScript 相同:

window.addEventListener('click', console.log)
window.addEventListener('touchstart', console.log)
window.addEventListener('touchmove', console.log)
window.addEventListener('touchend', console.log)
window.addEventListener('touchcancel', console.log)

另外可用unmonitorEvents(element[, eventType])来停止监听。

在这里插入图片描述

getEventListeners

getEventListeners(element)

印出已注册在元素上的监听器,以刚刚的例子来说,输入monitorEvents(element)后再输入getEventListeners(element)就会看到所有事件都被注册了一轮:
在这里插入图片描述
展开的话可以看到监听器的各种属性:

listener – 触发事件执行的Function
once – 该监听器只会触发一次
passive – 不能执行event.preventDefault(),常用在提升监听器的效能如 scroll
type – 监听事件类型
useCapture --监听器会在Capture阶段拦截事件
上述的属性都是能在执行addEventListener时提供的参数,记得在removeEventListener时也要填入相同的参数才能移除监听器。

const options: {
  capture: true,
  passive: true,
  once: false
}
window.addEventListener('click', console.log, options);
// window.removeEventListener('click', console.log, options);

queryObjects

queryObjects(object)

官方文件说明是返回Constructor 产生的所有Instances,不过笔者认为应该解释为:印出所有原型链包含该原型的物件。
在这里插入图片描述
可以看到以a为原型建立的b也会出现在queryObjects(A)的结果中。

另外由于queryObjects并不会直接return阵列,而是过了一下才印出来,这边利用右键>Store as global variable来把阵列放进变数temp1。

copy

copy(object)

copy能够把DOM、物件复制到剪贴簿,例如笔者有时候会用copy把物件转为JSON,贴到对话框来讨论API Spec,或是用Console来快速建立、修改假资料。
在这里插入图片描述

keys, values

keys(object), values(object)

印出物件自身的所有key或value,效果和Object.keys(object)、Object.values(object)相同,为何强调自身呢?如果是用in来遍历物件的各个属性,就会把Protoype链上的属性全都拿出来跑一遍:

const object = Object.create({ foo: 1});
object.bar = 2;
for (let key in object) {
  console.log(key)
}
// bar
// foo

除了是自身的key,还要enumerable。

如果想要确认属性是否是定义在物件自身可以用Object.prototype.hasOwnProperty:

for (let key in object) {
  if (Object.prototype.hasOwnProperty.call(object, key)) {
    console.log(key);
  }
}
// bar

至于为什么不用object.hasWonProperty(key),请参考下方程式码:

const object1 = {
  hasOwnProperty: function() {
    return false;
  },
};
const object2 = Object.create(null);

object1.key = 'key';
object2.key = 'key';

object1.hasOwnProperty('key'); // ?
object2.hasOwnProperty('key'); // ?

clear
clear()

虽然按下左上角的?就能把Console清乾净,但笔者还是习惯用clear(),就像在terminal输入clear一样。
在这里插入图片描述
注意在Preserve log 开启的状况下clear并不会清空Console。

小结

终于讲完了Console Utility Functions,明天将会继续讲一些在Console 内执行JavaScript 的小撇步。

本文链接http://www.dzjqx.cn/news/show-617477.html