前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >你还在瞒着我偷偷使用强制相等

你还在瞒着我偷偷使用强制相等

原创
作者头像
前端修罗场
发布于 2023-05-25 13:33:22
发布于 2023-05-25 13:33:22
16000
代码可运行
举报
文章被收录于专栏:Web 技术Web 技术
运行总次数:0
代码可运行

我们都知道JavaScript有== (强制相等)和===(严格相等)运算符进行比较。但你可能不知道它们两个究竟有什么不同,并且更重要的是,在 js 引擎中使用它们的时候发生了什么?

前面我们提到 == 是强制比较。强制意味着 VM 试图将进行比较的双方强制为相同的类型然后查看它们是否相等。以下我们列举了一些自动被强制相等的例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"1" == 1 // true
1 == "1" // true
true == 1 // true
1 == true // true
[1] == 1 // true
1 == [1] // true

你要知道,强制是对称的,如果a == b为真,那么b == a也为真。另一方面,只有当两个操作数完全相同时===才为真(除了Number.NaN)。因此,上面的例子都真实的情况下都是假真 (即,在 === 的情况下是 false 的)。

为什么强制相等有这样的问题,这要归咎与强制相等的规则。

强制相等的规则

实际的规则很复杂(这也是不使用==的原因)。但是为了显示规则有多么复杂,我通过使用===实现了==,带大家看看强制相等的规则到底多复杂:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function doubleEqual(a, b) {
  if (typeof a === typeof b) return a === b;
  if (wantsCoercion(a) && isCoercable(b)) {
    b = b.valueOf();
  } else if (wantsCoercion(b) && isCoercable(a)) {
    const temp = a.valueOf();
    a = b;
    b = temp;
  }
  if (a === b) return true;
  switch (typeof a) {
    case "string":
      if (b === true) return a === "1" || a === 1;
      if (b === false) return a === "0" || a === 0 || a == "";
      if (a === "" && b === 0) return true;
      return a === String(b);
    case "boolean":
      if (a === true) return b === 1 || String(b) === "1";
      else return b === false || String(b) === "0" || String(b) === "";
    case "number":
      if (a === 0 && b === false) return true;
      if (a === 1 && b === true) return true;
      return a === Number(String(b));
    case "undefined":
      return b === undefined || b === null;
    case "object":
      if (a === null) return b === null || b === undefined;
    default:
      return false;
  }
}

function wantsCoercion(value) {
  const type = typeof value;
  return type === "string" || type === "number" || type === "boolean";
}

function isCoercable(value) {
  return value !== null && typeof value == "object";
}

这是不是太复杂了,我甚至不确定这是正确的! 也许有你知道更简单的算法。

但有趣的是,你会发现在上面的算法中,如果其中一个操作数是对象,VM 将调用. valueof()来允许对象将自身强制转换为基本类型。

强制转换的成本

上面的实现很复杂。那么===== 要多浪费多少性能呢? 看看下面这张图,我用基准测试做了一个对比:

其中,图表中越高表示越快(即,每秒操作次数越多)。

首先我们来讨论数字数组。当 VM 注意到数组是纯整数时,它将它们存储在一个称为PACKED_SMI_ELEMENTS的特殊数组中。在这种情况下,VM 知道将 == 处理为 === 是安全的,性能是相同的。这解释了为什么在数字的情况下,===== 之间没有区别。但是,一旦数组中包含了数字以外的内容,== 的情况就变得很糟糕了。

对于字符串,===== 的性能下降了 50%,看起来挺糟的是吧。

字符串在VM中是特殊的,但一旦我们涉及到对象,我们就慢了 4 倍。看看 mix 这栏,现在速度减慢了 4 倍!

但还有更糟的。对象可以定义 valueOf,这样在转换的时候可以将自己强制转换为原语。虽然在对象上定位属性可以通过内联缓存,内联缓存让属性读取变得快速,但在超大容量读取的情况下可能会经历 60 倍的减速,这可能会使情况更糟。如图中最坏情况(objectsMega)场景所示,===== 慢15 倍!

有其他使用 == 的理由吗

现在,=== 非常快! 因此,即使是使用 === 的15倍减速,在大多数应用程序中也不会有太大区别。尽管如此,我还是很难想出为什么要使用 == 而不是 === 的任何理由。强制规则很复杂,而且它存在一个性能瓶颈,所以在使用 == 之前请三思。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
云厂商二次虚拟化限制
非裸金属的CVM已经是虚机,不支持二次虚拟化,业内主流厂商都不支持二次虚拟化(如果谁有发现,请分享下,谢谢)
Windows技术交流
2021/06/15
3.5K0
不要用过时安全性差的Windows系统和数据库
https://cloud.tencent.com/developer/article/2180366
Windows技术交流
2023/10/11
6620
远程windows服务器调用本地摄像头和声卡
需求:国内macOS电脑远程香港windows服务器,打开服务器里的chrome浏览器调用本地macOS电脑的摄像头进行视频会议
Windows技术交流
2022/01/18
12.2K7
Andriod模拟器网易腾讯那家强?
现在的模拟器总体上,基于两种工作模式运行,一种是基于虚拟化Hyper-V的,这个需要计算机硬件打开虚拟化,另一种是不依赖这个的,他们叫模拟引擎。
糖果
2021/08/12
2.4K0
公有云Windows Docker踩坑详述
备注:我用的香港服务器,听说海外机器安装docker、拉Windows镜像快一些,其中docker的安装貌似是从onegetcdn.azureedge.net这个站点下载数据的,这个站点在全球没有分布于国内的节点,只有海外节点,所以用国外服务器来搞会快一些。
Windows技术交流
2020/12/09
6.6K0
华为模拟器ensp怎么安装_ensp模拟器网页版
华为模拟器说实话有时候真的是很烦人,总是莫名其妙的出问题,而且网上教程一般也解决不了
全栈程序员站长
2022/11/04
3.7K0
华为模拟器ensp怎么安装_ensp模拟器网页版
Windows镜像如何一次性成功导入腾讯云
二、如何在VMware里创建能成功导入腾讯云的虚拟机(请严格按文档后面创建虚拟机的逐步截图来)
Windows技术交流
2021/06/18
4.4K0
软件检测到是虚拟机就退出了,怎么解决?
有些软件,比如某税务软件使用时提示是虚拟机就无法进行下一步了,加个子用户级别的白名单(hide_virtual_user),开任何白名单都需要时间生效,建议开白后等十几分钟再用这个子用户买的机器就绕过软件关于是否虚拟机的检测了,但即便绕过,毕竟还是不支持二次虚拟化,那些需要二次虚拟化才能正常运行的软件即便想办法安装上了也是会出现不稳定的情况。
Windows技术交流
2022/01/17
2.1K0
云服务器上可以运行雷电模拟器吗
随着游戏行业的发展,越来越多的玩家希望能够在云服务器上运行雷电模拟器,以享受更好的游戏体验和性能。但是,究竟云服务器是否能够开启雷电模拟器呢?本文将为大家分析一下这个问题,并提供实际操作的建议和指南。
华科云商小彭
2023/10/10
2.8K0
云服务器上可以运行雷电模拟器吗
win10总是莫名其妙卡死怎么解决
win10系统频繁死机怎么办呢?使用电脑时出现最多的问题就是运行卡顿,死机了。虽然有些和我们使用习惯有关,但是最大的影响因素还是软件兼容性以及硬件问题。今天,我就将解决方法分享给你们 win10系统是
用户8002245
2020/12/31
19.1K0
RemoteFX方案的兼容性跟多重因素有关
需求:国内macOS电脑远程香港windows服务器,打开服务器里的chrome浏览器调用本地macOS电脑的摄像头进行视频会议
Windows技术交流
2022/01/18
7230
普通cvm不支持windows sandbox,替代方案Sandboxie不错
平时跑第三方小软件,担心安全问题,在本地电脑上用vmware开个虚拟机跑一下很方便,在云服务器上由于自己没钱,买不起黑石,没法跑vmware(只有裸金属物理机才支持虚拟化,普通cvm不支持),那还想安全地运行第三方程序怎么办
Windows技术交流
2021/09/23
1.2K0
U盘pe(理论大白菜、优启通、微PE都可以) 装ESXI方案 (非通用UltraISO重做启动U盘),省U盘「建议收藏」
此文是我发的一篇的准备工作,因为ESXi 6.7刚发布的原因,很多同学等着升级,故而先写了出来。原文如下:
全栈程序员站长
2022/10/03
8.6K0
U盘pe(理论大白菜、优启通、微PE都可以) 装ESXI方案 (非通用UltraISO重做启动U盘),省U盘「建议收藏」
什么是裸金属服务器?
乍一看裸金属服务器这个名字,确实是让人感到困惑——服务器难道不都是金属的么?难道有木质或者塑料的?
鲜枣课堂
2020/08/11
19.1K1
什么是裸金属服务器?
如何判断服务器是否支持虚拟化
http://www.cpuid.com/softwares/cpu-z.html
Windows技术交流
2021/09/29
5.4K0
EVE-NG模拟器教程(二)——模拟器安装
上一篇文章已经介绍了 如何获取 EVE-NG 模拟器安装包,同时我们知道 EVS-NG 提供两种类型的安装包,一种是 OVF 包 (导入虚拟化平台使用,个人学习用),另一种是 ISO 镜像文件 (直接安装在物理机上使用,性能高),我们可以根据不同需要选择不同类型的安装包,这里我们已经把最新的两种类型的安装包都准备好了,如下,EVE-COMM-VM-112为 OVF包,EVE-20171007为 ISO镜像文件:
全栈程序员站长
2022/09/02
4.8K1
GPU机器如何支持DX、如何开启OpenGL、如何D3D兼容?安装Grid驱动!
GPU机器有2种,一种是GPU云服务器,一种是裸金属GPU,裸金属只能用公共镜像列表里的镜像
Windows技术交流
2021/09/18
9K1
EVE模拟器的安装使用
以前学习网络,没有一个好的模拟器,大家都用真实的设备做实验,但是效率太低了,而且每次学习新的内容需要自己插拔网线,搭建新的拓扑(或者使用万能拓扑),这样学习的效率十分低下,而且十分困难,导致那些本来对网络有兴趣并且想学习网络的人对网络望而却步! 现在的软件技术非常发达,模拟器功能非常的完善,我们只需要有一台个人电脑就可以将模拟器装进个人电脑里面,通过模拟器来搭建各种拓扑图,学习网络变得非常方便,而且效率十分的高,而且可以随时自己设计自己想要的拓扑来加深自己对网络知识的理解!
全栈程序员站长
2022/07/01
2.7K0
EVE模拟器的安装使用
VMware业务系统迁移上云方案
客户要将业务从自建的虚拟化数据中心迁移至UCloud,希望能够将多年前的VMware体系换到公有云体系。其中:
IT大咖说
2020/12/29
3.2K0
VMware业务系统迁移上云方案
模拟器选择
最近线上的问题有点多。各种兼容性的问题,还有手动测试遗漏的一些问题。如果用自动化来补充手工测试,线上很多问题都可以避免。 谈到自动化测试,我只能呵呵。 兼容性测试,靠手工,靠现有的几个机型,总是不能覆盖全。
赵云龙龙
2020/12/15
2K0
模拟器选择
推荐阅读
相关推荐
云厂商二次虚拟化限制
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验