当前位置: 首页 > Web前端 > JavaScript

用控制台画龙?

时间:2023-03-27 00:42:06 JavaScript

认识控制台一定是前端er最熟悉的朋友了。不管是console控制台还是consoleobject,做前端久了,打开网页总是莫名其妙自然而然就打开了控制台,有些顽皮的网站会故意在console输出一些有趣的东西,比如作为招聘信息,像百度的:别的不说,真的是年年更新,看着还挺刺激的。另外输出一些花里胡哨的字符图形也很常见,比如天猫:还有一些网站可能不喜欢调试,只要打开控制台就会自动进入调试模式,还是那种无限调试器。最简单的实现如下:setInterval(()=>{debugger},1000)不难破解,有兴趣的可以百度。不知道有没有人和我一样做前端多年,靠着一个console.log走遍天涯,好像console只是一个log方法。如果是这样,那么让我们在本文中一起详细了解控制台对象。我们知道console对象是宿主环境提供的,比如浏览器、nodejs,作为全局对象的一个??属性,不需要通过构造函数创建,直接使用即可。console对象的__proto__指向一个空对象,所以console对象的方法是挂在对象本身上的。在chrome控制台打印console时,可以看到如下方法或属性:console输出信息的方法可以接收多个参数,以逗号分隔,打印时会显示在同一行。它会改变线路。如果要换行,请使用控制台方式多次打印。另外,同样的方法在不同的浏览器上可能会有不同。由于大家基本都用chrome,下面大部分内容都是chrome下的效果。直接罗列api比较无聊,还是根据场景来看吧。场景一:输出普通的调试信息,比如数字、字符串、对象、数组、函数等,可以使用console.log或者console.info,这两种方式基本相同:场景二:想要输出不同层次的信息调试信息,比如警告信息或者错误信息调试级别的信息可以使用console.debug方法,控制台默认是不显示的,如果要看需要勾选控制台的相应选项:警告信息即可使用console.warn方法,会在这行信息中添加黄色背景和感叹号图标,同时显示堆栈信息:可以使用console.error方法添加红色背景和叉号icon到这行信息,同时显示堆栈信息:场景三:我想查看某个DOM元素的所有属性。比如我想查看body元素的所有属性,应该看什么:console.log(document.body)这样在控制台打印DOM结构,看不到细节。属性:Sowhattodo,可以用forin来遍历:for(letpindocument.body){console.log(p,document.body[p])}另一种简单的方法就是把它当作一个数组Anitemoranattributevalueofanobject:console.log([document.body],{body:document.body})当然,以上都不是最简单的,最简单的就是直接使用console.dir方法:场景四:如果想查看具体的调用位置、调用堆栈等信息,只需要找到调用位置即可,log、info、error等方法一应俱全。如果想查看调用栈信息,可以使用console.assert,console.error,console.warn和特殊方法console.trace,trace方法可以不带参数:场景五:有时候控制台写的太多了打印出来的信息太多,无法一眼看出是哪里,也不好区分哪些是相关的这个可以手动把其他的全部注释掉,只留下这次需要的(whatdoyouwant说什么?),当然,如果你愿意多敲几行代码,也可以使用console.group方法进行分组显示,使用console.groupEnd方法结束分组,可以嵌套多个levels:console.group(xxx)xxxconsole.groupEnd()爱情场景一:实现上面的百度效果。控制台需要使用\n:console。log('每一个星球都有一个驱动核心,\n每一种思想都有一颗影响力的种子\n感受世界的温度,\n你也可以在年轻的时候成为改变世界的原动力,\n百度珍惜你拥有的一切你的潜力。\n你的潜力是改变世界的原动力!')输出红字可以使用占位符,占位符格式为:console.log('%xothercharacters','xxx',[xxx,xxx...])使用%c占位符设置样式,可以使用多个,将样式应用于占位符后的字符,替换占位符后剩余的参数也会正常打印:console.log('%cBaidu2021校园招聘简历投递:','color:red','https://talent.baidu.com/external/baidu/campus.html')支持常用样式属性:console.log('%c街%c角%csmall%cforest','font-size:20px;margin-right:5px','color:#58A7F2','font-size:24px;background:#F4605F;color:#fff;padding:5px','边框r:1pxsolid#8F4CFF;padding:10px;border-radius:50%')除了%c,还有其他几个占位符:%i,%f,%s等,因为不常用,就不详细介绍了。场景2:让我们在控制台上画一条龙。好像最近很流行画龙。好的,我来满足你:console.log('%c','background-image:url(/dragon.jpg);background-size:100%;padding:267px300px;')ps。不知道为什么在chrome里不行,不过上面是在edge浏览器上的效果。(用图片很可惜,图片支持很差,估计很多浏览器不能显示,能不能换个方法?)要求挺多的,图片不能用,所以就这样了和上面提到的天猫一样。让我们用字符来画猫,但是我们需要先把图片转换成字符。原理和大帅的文章一样,只是把div换成了字符。使用canvas获取图片的像素数据后,使用两层循环嵌套,外层遍历高,内层遍历宽,迭代高的时候加一个换行符\n,迭代宽的时候加一个换行符,根据当前像素点的r,g,b信息来判断是加入空字符还是非空字符,最后拼接出来的字符就是我们要打印的字符,但是需要注意的是因为我们是一个pixel对应一个字符,但是字符的实际大小必须大于1如果像素很大,比如16px的文字,那么我们最终得到的字符图形会是原图的16倍,这显然太大了并且不能在控制台显示,所以需要缩小。怎么缩小呢,有两种方法,一种是缩小图片。图片越小,像素越少。二是减少采样点。例如,我们每10px取一个点。问题是最终图形可能会与原始图片有所偏差。//加载龙的图像letimg=newImage()img.src='./Dragon.jpg'img.onload=()=>{draw()}//将图像绘制到画布中constdraw=()=>{constcanvas=document.getElementById('canvas')canvas.width=img.widthcanvas.height=img.heightconstctx=canvas.getContext('2d')ctx.drawImage(img,0,0,img.width,img.height)//获取像素数据constimgData=ctx.getImageData(0,0,img.width,img.height).data//Joincharactersjoin(imgData)}//Joinpixeldataintocharactersconstjoin=(data)=>{letgap=10letstr=''for(leth=0;h=190){//Lightstr+=''}else{//Darkstr+='#'}}}console.log(str)}的效果如下:可以看到虽然大致的形状出来了,细节很少很多,另一种缩小图片的方法很有趣,你可以自己试试,效果可能比这个好,但是不用这么麻烦,有很多网站可以帮助您直接转移,例如:https://www.degraeve。com/img2txt.php。情场一:如何更方便的打印对象?我们都知道它是引用类型。在平时的开发中,我们经常打印一个对象或者一个数组。修改了很多次,每次修改后都想看到此时此刻的数据。不幸的是,直接使用console.log或dir等方法最终会显示对象最后时刻的数据:letobj={a:1,b:[1,2,3]}console.log(obj)obj.a=2console.error(obj)obj.b.push(4)console.dir(obj)可以看到旁边有个感叹号,会显示一行提示:Thisvaluewasevaluateduponfirstexpanding,之后可能已经变了,也就是说这个值计算了一次,但是后面可能会变,所以我们经常使用:console.log(JSON.stringify(obj))或者深拷贝然后打印,有没有更简单的方法?我们可以在console中添加两个方法,一个叫console.obj,深拷贝然后打印,另一个叫console.str,在打印前序列化对象:console.obj=function(...args){letnewArgs=args.map((item)=>{if(Object.prototype.toString.call(item)==='[objectObject]'||Array.isArray(item)){returndeepClone(item)}else{returnitem}})console.log(...newArgs)}console.str=function(...args){letnewArgs=args.map((item)=>{try{letobj=JSON.stringify(item)返回obj}catch(e){returnitem}})console.log(...newArgs)}场景二:如何在生产环境中移除控制台如果要在生产环境中移除控制台,可以通过webpack插件,也可以拦截console对象方法,判断是否是生产环境,如果是,不打印log,我们重写console对象:letoldConsole=window.consoleletnewConsole=Object.create(null)//其他方法这里暂时省略;['log'].forEach((method)=>{newConsole[method]=function(...args){//非开发环境直接返回if(process.env.NODE_ENV!=='development'){return}oldConsole[method](...args)}})window.console=newConsole重写控制台可用于任何需要知道控制台调用的场景,对于例如,前端监控日志在nodejs和浏览器中报告控制台有点不同是的,这是显而易见的。毕竟命令行肯定没有浏览器那么强大:如图所示,log、info、error、warn、debug这几个method表面上看起来没什么区别,error和warn又不像浏览器.还有栈信息,trace还是一致的,对象的打印也是直接展开的,所以如果要格式化显示,需要自己处理打印的对象。比如对于纯对象:console.log(JSON.stringify({a:1,b:[1,2,3]},null,4))另外,%c这个占位符显然没有作用。如果想打印出一种颜色,可以使用chalk之类的工具库,如果命令行不支持其他一些方法的输出效果,最终会直接调用console.log来处理。浏览器环境下没有Console类,但是在nodejs中有。有两种获取方式:const{Console}=require('console')const{Console}=console通过Console类,可以根据需要传入参数来实例化一个新的console实例:/*stdout:可写流,用于输出信息stderr:可选的可写流,用于输出错误信息,不传则使用stdoutignoreErrors:写入底层流时忽略错误*/newConsole(stdout[,stderr][,ignoreErrors])默认全局控制台输出到标准输出流和标准错误流,相当于:newConsole(process.stdout,process.stderr)然后可以选择把Log输出到指定文件:constoutput=fs.createWriteStream('./stdout.log')consterrorOutput=fs.createWriteStream('./stderr.log')newConsole(output,errorOutput)再见,终有离别,各位有缘人,下期见时间~