2021-05-26

  浏览器眼中的0

  知识图谱进阶必读:一文读懂大规模图谱数据如何高效存储和检索!>>>

  0作为一个特殊的符号,经常会跟浏览器打交道,在不同的场景下,0代表的意思不尽相同,因此浏览器眼中的0不一定就是符合人们感官上的认识,那究竟浏览器会怎么对待它呢,今天我们就来探究一下各种场景中0的含义及浏览器的处理方式。

  1.setTimeout

  setTimeout在js中常用来推迟任务的执行,可以通过第二个参数设置延迟的毫秒数(如果不设置,默认为0),在一些代码中,可以看到delay=0的情况,如下

  window.setTimeout(() => { ...... }, 0);

  了解js的同学应该知道,setTimeout的回调函数不会在定时器超时后立即执行,如果delay大于0,比较好理解,但delay是0的时候呢,浏览器会怎么对待呢,这里要分两种情况: 1.)timer嵌套 'Timers can be nested; after five such nested timers, however, the interval is forced to be at least four milliseconds.'也就是setTimeout嵌套超过5层的,并且延迟不到4ms,才会变成4ms,同样适用于setInterval,因此在这种情况下,delay=0其实会被设置成4; 2.)timer没有嵌套 在没有嵌套情况下,对于chrome来说,delay=0也会设置成1; 说完浏览器的处理方式之后,我们来看看网上搬过来的一个例子吧:

  setTimeout(()=>{console.log(5)},5)

  setTimeout(()=>{console.log(4)},4)

  setTimeout(()=>{console.log(3)},3)

  setTimeout(()=>{console.log(2)},2)

  setTimeout(()=>{console.log(1)},1)

  setTimeout(()=>{console.log(0)},0)

  chrome打印结果:1 0 2 3 4 5; firefox打印结果:0 1 2 3 4 5; edge打印结果:1 2 0 3 4 5; qq浏览器打印结果:1 0 2 3 4 5; 360浏览器打印结果:1 0 2 3 4 5; 从上面的打印结果来看,firefox是符合代码预期的,edge打印与chrome稍有不同,应该是edge处理delay=0情况稍有不同(设置成了2),qq和360浏览器跟chrome保持一致。 0ms定时器 在MDN文档上,还说到一种实现0ms延时的定时器的实现方案,大体思路是自定义一个setZeroTimeout 方法,通过 postMessage 来触发定时回调的执行,具体可看 https://dbaron.org/log/20100309-faster-timeouts ; node的setTimeout 说完浏览器中的setTimeout,我们再来看看nodejs中的是否一样呢,可以通过nodejs的源代码窥探一二:

  // https://github.com/nodejs/node/blob/master/lib/internal/timers.js

  function Timeout(callback, after, args, isRepeat, isRefed) {

  after *= 1; // Coalesce to number or NaN

  if (!(after >= 1 && after <= TIMEOUT_MAX)) { // const TIMEOUT_MAX = 2 ** 31 - 1;

  if (after > TIMEOUT_MAX) {

  process.emitWarning(`${after} does not fit into` +' a 32-bit signed integer.' + '\nTimeout duration was set t 1.', 'TimeoutOverflowWarning');

  }

  after = 1; // Schedule on next tick, follows browser behavior

  }

  看过源代码后,就知道node的处理策略了如果delay=0,会设置为1,注释也说得很清楚了,是为了遵循浏览器的行为。

  2.+0&-0

  虽然很少用到,但是js中确是存在+0和-0的,那么有什么区别呢:

  +0 === -0; // true

  +0 === 0; // true

  -0 === 0; // true

  可以看到,通过全等比较,+0,-0和0都是相等的,那是否就可以认为这三者就是一样的呢,还不能这么轻易下结论,有时候很有必要区分三者,那么如何判断呢,es6新增了一个方法Object.is(value1, value2),可以用来判断,具体效果如下:

  Object.is(0, -0); // false

  Object.is(+0, -0); // false

  Object.is(+0, 0); // true

  这里还需要说明的一点就是+0和0其实就是一样的,因为+0等效Number(0),因此Object.is(+0, 0)是符合预期的,这里顺带说一下Object.is的比较逻辑,根据MDN文档描述, Object.is() 方法判断两个值是否为同一个值。如果满足以下条件则两个值相等:

  都是 undefined

  都是 null

  都是 true 或 false

  都是相同长度的字符串且相同字符按相同顺序排列

  都是相同对象(意味着每个对象有同一个引用)

  都是数字且

  都是 +0

  都是 -0

  都是 NaN

  或都是非零而且非 NaN 且为同一个值

  与== 运算不同。 == 运算符在判断相等前对两边的变量(如果它们不是同一类型) 进行强制转换 (这种行为的结果会将 "" == false 判断为 true ), 而 Object.is 不会强制转换两边的值。 与=== 运算也不相同。 === 运算符 (也包括 == 运算符) 将数字 -0 和 +0 视为相等 ,而将Number.NaN 与NaN视为不相等.

  最后来看下如何生成-0和+0吧:

  1/-Infinity; // -0

  0*-1; // -0

  1/+Infinity; // +0

  0*+1;// +0

  3. +[]

  由于存在类型转换,因此在判断相等时,会有这样的情况:

  '' == 0; // true

  [] == 0; // true

  +[] == 0; // true

  这里我们说一下+[]的情况,很容易理解,+相当于Number([]),最终会转换成0,这没什么大不了,如果是下面这段代码呢:

  (![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[+!+[]+[!+[]+!+[]+!+[]]]+[+!+[]]+([+[]]+![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[!+[]+!+[]+[+[]]]

  其实代表的就是alert(1), http://www.jsfuck.com/ 这个奇葩网站专门干这事的,原理就是使用的类型转换,把我们熟悉的代码变成了这样,真是骚操作。

  4.font-size

  font-size在css中使用频繁,浏览器通常会默认设置成14px或者16px。如果设置成0呢?

  .foo {

  font-size: 0;

  }

  foo

  文字真的就没有了,这符合预期,但如果设置的值小于12(非负),各浏览器处理稍有不同,chrome/edge浏览器会设置最小字体为12px,firefox严格按照给定的值来显示。 font-size:0的用处 在布局过程中,经常会生成空白字符,例如:

  a

  b

  box1和box2高度其实是略高于实际的内容的,而且box1的两个span中间有间隙,没有紧挨着,因为空白字符的原因,引用css规范说明:On a block container element whose content is composed of inline-level elements, 'line-height' specifies the minimal height of line boxes within the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a "strut.",大意就是一个块级容器元素内容区域由inline-level元素组成的;而这些linline-level元素被放在每一行的line-box里面,line-box高度是由它所有子元素的高度计算得出的。浏览器会计算这一行里每个子元素的高度,再得出 line-box 的高度(具体来说就是从子元素的最高点到最低点的高度)。默认情况下,一个 line-box 总是有足够的高度来容纳它的子元素,而每一个行框可以想象为默认会有一个宽度为0的空白节点,字体大小和行高会影响该节点,具体规范可查看 https://www.w3.org/TR/CSS2/visudet.html#line-height。 说完规范后,再来分析一下box1和box2的效果,为了便于理解,下面的代码手动加入了一个[x]符号,代表strut:

  a b

  [x]

  [x]

  box1的两个span发生了换行,相当于中间有个空格,因此会有间隙,如果span不换行,那么中间的空隙也就没有了。由于存在[x],而且vertical-align:baseline的缘故,span/img和[x]的baseline对齐之后,[x]处于baseline以下的部分会撑开整个line-box的高度,因此会外部块级容器的高度会略高一些,说得不清楚,我们还是上一张图来说明吧:

  

图片描述

 

  粉色的线是图片的baseline,红色的线是strut的baseline,对齐之后strut的baseline下面还有一部分高度,box的最终高度就是img的顶部到strut底部之间的距离。分析完成因后,终于可以使用font-size:0来解决问题了,在box上设置font-size:0后,strut就相当于没有了,因此就不存在高度撑开的问题了,当然这里还可以改变img的vertical-align属性来修复这个问题,比如img{ vertical-align:bottom; }那么img的粉色线就跟strut的底部对齐了,也就不会撑开容器高度了,这里说了box2,box1原理差不多,这里涉及到vertical-align的知识了,可查阅https://www.w3.org/TR/CSS2/visudet.html#vertical-align 进行了解。

  5.width&height

  width和height也是可以设置成0的,效果也是符合我们预期的,但如果我们的意图是想通过设置0把元素隐藏的话,一般情况下会采用如下方案:

  .visually-hidden {

  clip: rect(0 0 0 0);

  clip-path: inset(50%);

  height: 1px;

  width: 1px;

  overflow: hidden;

  position: absolute;

  white-space: nowrap;

  }

  有些屏幕阅读器会忽略width和height等于0的元素,因此这里特意设置成1px,当然关于元素的隐藏还有很多实现方案,有兴趣可参考【1】;

  6.line-height

  line-height及行高,原意是baseline之间的高度,在css中就是一行的高度。默认情况下,line-height是跟具体字体定义相关联的,一般都是font-size的1.x倍,如果设置成0,在不同类型元素上的情况是不一样的,可分为如下三种情况: 1.)非置换行类元素 line-height定义的是最终参与计算line-box(行盒)的高度的值,而不会影响non-replaced inline element(非置换行类元素)的实际高度;

  a // class为foo的span高度不会受样式影响

  2.)行类块级元素 会影响元素高度,如果line-height设置为0,那么该元素高度就变成了0,如果设置了height,那么height将会起作用; 3.)块级元素 当块级元素包含inline-level(display:inline|inline-block)元素时, 行高定义的每一个line-box(行盒)的最小高度,此外height也能影响块级元素的最终高度,height比line-height有更高优先级,当没有height情况下,line-height起作用; 上面提到了line-box,如果有不了解的同学,可以看一下文末的链接【2】;

  7.transform

  transform常用来做样式变化和动画,在有时候,会设置成如下形式:

  transform: translateZ(0);

  这其实是为了启用GPU加速渲染,元素会单独在一个绘制层(Layer)里进行绘制,而不会对其他层产生影响,因此也就少了很多计算和合成的功能,而且不会阻塞主线程,动画会更加流畅,当然元素设置太多会导致性能降低,因为需要内存的维护。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。
2021-03-26 20:54:33,596 - Model - INFO - Epoch 1 (1/200): 2021-03-26 20:57:40,380 - Model - INFO - Train Instance Accuracy: 0.571037 2021-03-26 20:58:16,623 - Model - INFO - Test Instance Accuracy: 0.718528, Class Accuracy: 0.627357 2021-03-26 20:58:16,623 - Model - INFO - Best Instance Accuracy: 0.718528, Class Accuracy: 0.627357 2021-03-26 20:58:16,623 - Model - INFO - Save model... 2021-03-26 20:58:16,623 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 2021-03-26 20:58:16,698 - Model - INFO - Epoch 2 (2/200): 2021-03-26 21:01:26,685 - Model - INFO - Train Instance Accuracy: 0.727947 2021-03-26 21:02:03,642 - Model - INFO - Test Instance Accuracy: 0.790858, Class Accuracy: 0.702316 2021-03-26 21:02:03,642 - Model - INFO - Best Instance Accuracy: 0.790858, Class Accuracy: 0.702316 2021-03-26 21:02:03,642 - Model - INFO - Save model... 2021-03-26 21:02:03,643 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 2021-03-26 21:02:03,746 - Model - INFO - Epoch 3 (3/200): 2021-03-26 21:05:15,349 - Model - INFO - Train Instance Accuracy: 0.781606 2021-03-26 21:05:51,538 - Model - INFO - Test Instance Accuracy: 0.803641, Class Accuracy: 0.738575 2021-03-26 21:05:51,538 - Model - INFO - Best Instance Accuracy: 0.803641, Class Accuracy: 0.738575 2021-03-26 21:05:51,539 - Model - INFO - Save model... 2021-03-26 21:05:51,539 - Model - INFO - Saving at log/classification/pointnet2_msg_normals/checkpoints/best_model.pth 我有类似于这样的一段txt文件,请你帮我写一段代码来可视化这些训练结果
02-06

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值