[译] 如何处理 JavaScript 比较中的临界情况

JavaScript通过临界区实现线程同步(附完整源码) 阅读详情
  • 原文地址:https://medium.com/javascript-in-plain-english/how-to-handle-comparison-corner-cases-c96ae9a17d4a

  • 原文作者:Alen Vlahovljak

  • 译文出自:"掘金翻译计划"(https://github.com/xitu/gold-miner)

  • 本文永久链接:https://github.com/xitu/gold-miner/blob/master/article/2020/how-to-handle-comparison-corner-cases.md

????Joshua Aragon 拍摄并发布在 ????Unsplash

“在任何一项足够先进的技术和魔法之间,我们无法做出区分。” — Arthur C. Clarke (????克拉克基本定律三)

在我们开始熟悉 JavaScript 的临界情况之前,我想先区分一下 临界情况(Corner Case) 和 边界情况(Edge Case)。

我们可以说 边界情况(Edge Case)是一种仅发生在最小化或最大化参数时的问题。预测这种问题是一项有益之举,因为这些情况可能会被忽视或低估。比如,一台全力运转的 PC 可能会过热,其性能也可能有所折损。

我也想介绍另一种 边界情况(Boundary Case)(这也是一个值得怀疑的问题)。它可能会发生在某个参数逾越了最小化或最大化限制的时候。

那么 临界情况 呢?我并不想给出任何定义,因为在你看过下面的例子之后,你将能自己做到这点。

你将难以置信

如果我问你某些事情能否等于其自己的否定,你的答案会是什么?你肯定会说这是一派胡言,但是:

var arr1 = [];
var arr2 = [];

if (arr1 == !arr2) {
    console.log("Yes, it's true!");
}

if (arr1 != arr2) {
    console.log("It's true again!");
}

你可能会认为 JS 是一个疯狂的语言,并且这本不应该发生在 JS 这样流行的语言中。这个例子看起来很愚蠢,因为你在实际中绝不会对变量去比较其自身的否定。但这是个帮助你理清思绪的绝佳例子。

你压根不应该比较数组和否定的数组。 不应该以这种方式设计代码。上例就是个绝佳的反例。

在下一个例子中,我将细致地解释发生了什么,所以你会对算法做了什么有个清楚的想象:

var arr1 = [];
var arr2 = [];


//1. arr1 == !arr2
//2. [] == false 
//3. "" == false
//4. "" == 0
//5. 0 == 0 
//6. 0 === 0 
if (true) console.log("Yes, it's true!");

首先,我将引用 ????文档 中的规则。在以上代码的第 6 行,比较了一个基本类型值和一个非基本类型值。在这种情况下,采用规则 №11 。该算法的结果是一个空字符串。

在下一步中,将一个空字符串和 false 相比较。根据算法,采用规则 №9 。再下一步(第 8 行)则采用规则 №5 。第 5 步成了比较两个数字。因为使用了相等性比较,我们将会调用严格相等性比较算法。

最后一步从严格相等性比较中返回了一个 true。第二个例子更实用一点,因为我们使用了不等于(双等于号的否定)- 检查是否强制相等:

var arr1 = [];
var arr2 = [];


//1. arr1 != arr2
//2. (!(arr1 == arr2))
//3. (!(false))
if (true) console.log("It's true again!");

鉴于我们比较的是两个非基本类型,这就意味着会执行一个同一性比较。 等同于采用了严格相等性比较。

别惹布尔值

让我们谈谈布尔值极其与抽象相等性的联系。这是你会经常碰到的问题。我们应该看看会发生的临界情况:

var students = [];


if (students) {
    console.log("You can see this message!");
}

if (students == true) {
    console.log("You can't see this message!");
}

if (students == false) {
    console.log("Working!");
}

明确的比较有时反倒会带来不必要的麻烦。 在第二个 if 子句中,我们将数组和布尔值做了比较。你可能认为该操作的结果应当为布尔值 true,但并非如此。严格相等性比较也有同样的效果。

比较一个数组和一个布尔值会引起许多临界情况。在我们看例子之前,我要给你个提示:永远不要对布尔值(true 和 false)使用双等于号。让我们分析下算法是如何工作的:

var students = [];


//** if(students) **//
// 1. students 
// 2. Boolean(students)
if (true) console.log("You can see this message!");

//** if(students == true) **//
// 1. "" == true
// 2. "" == 1
// 3. 0 === 1
if (false) console.log("You can't see this message!");

//** if(students == false) **//
// 1. "" == false
// 2. "" == 0
// 3. 0 === 0
if (true) console.log("Working!");

首个 if 子句是自解释的,所以我不会费时赘述。一如之前的例子,我引用了 ????文档 中的规则。当其中一个被比较的值是非基本类型时,比较数组和布尔值会调用 ????ToPrimitive() 抽象操作(规则 №11)。

之后的三步(译注:第二个 if 子句)直接了当。首先,将一个布尔值转换为一个数字(规则 №9:????ToNumber(true)),接下来字符串变为数字(规则 №5:????ToNumber(“”)),最后一步则是执行一次严格相等性比较。第三个子句同样如此。

强制转换的风险之一就是抽象操作 ToNumber()。我不确定将一个空字符串转换成 0 是否应该。返回 NaN 其实会更好,因为 NaN 表示了一个非法的数字。

推论:无意识的输入总会产生无意识的输出。不必总是显式比较,隐式比较有时比前者更佳。

检查数组值的存在性最好的办法就是明确的检查 .length 以确定其是个字符串还是个数组:

const arr1 = [1, 2, 3];
const arr2 = [];


if (arr1) {
    console.log("You should see this message!");
}

if (arr1.length) {
    console.log("Array is not empty!");
}


if (arr2) {
    console.log("You should not see this message!");
}

if (arr2.length) {
    console.log("You can't see this message!");
}

深层检测更为可靠。如你所见,一个空数组将返回 true (强制转换为布尔值之后)。处理对象是也应采用同样的办法 -- 总是做深层检查。当我们想要确定类型是字符串还是数组时,使用 typeof 操作符(或 Array.isArray() 方法)。

说明

你必须遵守若干准则以避免陷入临界情况的陷阱。随处使用的双等号是把双刃剑。 应谨记当两侧被比较的值是 0、一个空字符串或只包含空格的字符串时,使用双等号是个不好的做法。

下一件应牢记之事是避免对非基本类型使用双等号。唯一能使用它的时机是一致性检查时。 但我也不能说这是 100% 安全的,因为它已经足够接近临界情况,不值得冒险。

????ECMAScript 6 引入了一个新的工具方法 ????Object.is()。借助该方法,我们终于可以在无副作用的情况下执行一致性比较。最后我们可以讲,使用双等号只对基本类型安全,对非基本类型则不安全。

最后但并非最不重要的是要避免对布尔值(true 和 false)使用双等于号。允许隐式的布尔值强制转换(调用 ToBoolean() 抽象操作)会更好。如果不能启用隐式强制转换,又只能对布尔值(true 和 false)使用双等号,那就应该 改为三等号。

总结

大多数临界情况都能通过重构代码得以避免。



--End--

查看更多前端好文
请搜索 fewelife 关注公众号

转载请注明出处

NLP高频面试题(一)——Transformer的基本结构、作用和代码实现 本文详细介绍了Transformer模型的基本结构和PyTorch代码实现过程。首先解析了Transformer的核心组成部分,包括嵌入层、多头自注意力机制、位置编码、前馈神经网络、编码器和解码器等模块,并通过清晰的代码示例逐步展示了如何在PyTorch中构建完整的Transformer模型。文末提供了一个可运行的简单示例,帮助读者快速理解并实践Transformer的核心原理与实现方法。 阅读详情

相关推荐

手把手教你用Xilinx SelectIO IP核搞定ADS42LB69高速ADC的DDR数据采集(附仿真调试技巧)

本文详细介绍了如何使用Xilinx SelectIO IP核实现ADS42LB69高速ADC的DDR数据采集,包括IP核配置、仿真验证和硬件调试技巧。通过精准的时序控制和实战调试方法,解决高速数据采集中的时序对齐问题,提升系统稳定性和可靠性。特别适合FPGA工程师和高速ADC接口设计者参考。

weixin_42533622的博客 152

corner case和edge case的差别

What is the difference between an edge case and a corner case?

qq_35466511的博客 3964

UE5新手必看:如何用蓝图系统快速打造赛车游戏(含Chaos Physics配置)

本文为UE5新手提供使用蓝图系统快速打造赛车游戏的完整指南,涵盖Chaos Physics配置、载具蓝图架构设计、控制逻辑实现等关键步骤。通过详细的实战案例和优化技巧,帮助开发者高效构建具备专业物理反馈的赛车游戏原型。

weixin_29001327的博客 387

综述|寻找自动驾驶中的关键场景

作者丨黄浴@知乎来源丨https://zhuanlan.zhihu.com/p/426572273编辑丨3D视觉工坊arXiv在2021年10月16日上传论文“Finding Critic...

3D视觉工坊 1904

多传感器标定全栈系统学习教程

无论是激光雷达(Lidar)、毫米波雷达(Radar)、相机(Camera)还是惯导(IMU),传感器之间的精确标定直接决定了系统的可靠性与性能。本文将以系统化的视角,梳理多传感器标定的核心知识体系,并分享一套覆盖全栈技术的学习路径。Calibration)是实现点云与图像融合的前提,而雷达与车辆的标定(Radar2Car)则是精准速度估计的关键。:Lidar2Car、Camera2Car的快速标定流程,标定板布置规范。:从单传感器标定入手(如相机内参),逐步过渡到多传感器联合标定。

weixin_41792788的博客 904

[ESP32S3N16R8][LVGL8.3.0][IDF5.2.3]ST7701S RGB屏幕驱动[vscode最详细配置]

ST7701S ESP32S3 基于ESP-IDF5.2.3编写,编程环境为vscode。本教程详细讲述了esp32s3配置st7701s屏幕驱动以及gt911触摸驱动并关联到lvgl8.3.0,使用IDF5.23示例rgb_panel进行测试删除了其里面的屏幕驱动,改为单独编写屏幕和触摸驱动,最后完成了实列。

qq_44022379的博客 2604

比较适合lstm处理的情况_如何处理比较极端的情况

比较适合lstm处理的情况 重点 (Top highlight) JavaScript算法可能是“不可预测的”! (JavaScript algorithm can be “unpredictable”!) “Any sufficiently advanced technology is indistinguishable from magic.” “任何足够先进的技术都无法与魔术区分开。” —...

weixin_26717681的博客 784

Anthropic三件套重构AI工作流:Claude Code、Design与桌面宠物实战指南

AI协作已从单点工具迈入系统化工作流阶段。理解AI作为‘协作者’而非‘执行器’的本质,是提升工程效率的关键前提;其核心在于对任务调度、自适应推理与人机交互边界的重新定义。Claude Code的xhigh effort机制体现了分层推理的工程智慧,Claude Design以HTML为原生设计语言实现设计-代码一体化,而桌面宠物则将抽象的token消耗具象为可感知的硬件反馈。这些能力共同指向一个趋势:AI工作流正从prompt调参走向契约式委派、从界面割裂走向跨模态统一。本文结合Opus 4.7最新实践,解

a4512138的专栏 484

js实现一个异步锁,超时自动释放,队列等待

js实现异步锁,超时自动释放,队列等待。异步锁是一种用于控制并发访问的锁机制,主要用于多线程/多任务环境下。异步锁允许多个任务并行执行,但是只允许一个任务在同一时间获取锁并执行临界区代码,其他任务需要等待该锁释放后才能获取锁并执行自己的临界区代码。异步锁实现了互斥访问的机制,确保了同一时间只有一个任务可以访问共享资源。当一个任务获取了锁并执行临界区代码时,其他任务需要等待,直到锁被释放才能获取锁并执行自己的临界区代码。异步锁的实现可以基于各种机制,如互斥量、信号量等。

爱音乐的程序猿的博客 913

【开发必备插件】iframe嵌套报“拒绝连接请求”的本地解决方法

关键词:iframe 拒绝连接、X-Frame-Options、Chrome 插件、前端调试、Allow X-Frame-Options前几天我在本地项目里调试一个第三方网站的嵌入页面时,遇到了一个非常经典的报错:xxx.com 拒绝了我们的连接请求。熟悉的老前端们一眼就知道——这是。但对于日常开发来说,我们经常需要在本地测试 iframe 嵌套外部页面(比如嵌第三方登录页、支付页、可视化报表系统等)。而线上站点配置了或DENY时,就会直接导致 iframe 加载失败。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1540

IEC 61400-1:2019 附录 C 湍流模型全面解读

IEC 61400-1:2019 附录 C 全面解读

weixin_46713695的博客 471

比较array相等_[译] 如何处理 JavaScript 比较中的临界情况

原文地址:https://medium.com/javascript-in-plain-english/how-to-handle-comparison-corner-cases-c96ae9a17d4a原文作者:Alen Vlahovljak译文出自:"掘金翻译计划"(https://github.com/xitu/gold-miner)本文永久链接:https://github.co...

weixin_35878683的博客 94

STM32 HAL PWM (占空比) -电机软启动不到位解决

为了避免电机启动电压大造成设备损坏,或者供电不足导致重启,通常在对启动都需要一个PWM进行软启动,下面对PWM电机软启动详细介绍。

weixin_44597885的博客 866

如何处理 JavaScript 比较中的临界情况

原文地址:https://medium.com/javascript-in-plain-english/how-to-handle-comparison-corner-cases-c96...

前端开发博客 385

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

比较array相等_如何处理JavaScript比较中的临界问题

原文地址:https://medium.com/javascript-in-plain-english/how-to-handle-comparison-corner-cases-c96ae9a17d4a原文作者:Alen Vlahovljak译文出自:"掘金翻译计划"(https://github.com/xitu/gold-miner)“在任何一项足够先进的技术和魔法之间,我们无法做...

weixin_39601794的博客 104

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

JavaScript 日期比较——如何在 JS 中比较日期

进来看看呗!

qq_51201134的博客 4898

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

JS中的字符串比较

如果比较的类型不同,首先会进行隐式转换,就是将两边的类型自动转成一致再对比。 比较首先分为以下几种情况: 1.纯数字和纯数字比较 直接依据数学运算,没啥说的。 2.纯数字和数字型字符串比较 (30 > '20'); //true 数字型字符串会转成纯数字再与前面的纯数字比较,即 20 与 30 相比谁大? 3.纯数字和非数字字符串比较 ('a' > 96); //false 这种情况下,js 会将字符串转成数字,js 转数字的方法:parseInt(‘a’),如果解析不到数字,则将返回一.

MrQiu的博客 3779

详解 javascript 中的比较

11.9.3 抽象相等比较算法 比较运算 x==y, 其中 x 和 y 是值,产生 true 或者 false。这样的比较按如下方式进行: 若 Type(x) 与 Type(y) 相同, 则 若 Type(x) 为 Undefined, 返回 true。 若 Type(x) 为 Null, 返回 true。 若 Type(x) 为 Number,

xxmeng2012的专栏 493

Dinero.js:JavaScript 和 TypeScript 中的货币处理库

Dinero.js 是一个开源的 JavaScript 库,旨在帮助开发者安全地在 JavaScript 和 TypeScript 中创建、计算和格式化货币。该项目主要使用 TypeScript 编写,保证了类型的严格性和代码的健壮性。 ## 1. 项目基础介绍和主要编程语言 Dinero.js 是一个专门用于处理货币值的库,它为开发者提供了一种简便、安全的方式来处理货币相关的计算和格式化问题...

gitblog_00914的博客 902

JS实现日期比较大小(JavaScript)

JS代码中经常需要做日期大小比较: 这边做个总结: 方法一: function compareDate(dateTime1,dateTime2) { var formatDate1 = new Date(dateTime1); var formatDate2 = new Date(dateTime2); if(formatDate1 > formatDate2) ...

WangHuanToBeBest 6万+

Resemble.js: JavaScript 图像分析与比较工具

--- ## 项目基础介绍及编程语言 Resemble.js 是一个基于 JavaScript 的开源项目,专注于提供图像的分析与比较能力,利用 HTML5 技术。它允许开发者在前端或通过 Node.js 环境执行图像相似度检测,适用于自动化测试、图片处理应用等多种场景。这个项目主要使用 **JavaScript** 作为开发语言,并且兼容 Node.js 环境,使得其在前后端都能灵活运用。 ...

gitblog_00360的博客 1037

JavaScript中的数值比较

作为一个还在学习的前端小码农,昨天刚刚学习JavaScript中的数据,由于在和同学讨论其他的问题,老师讲的记得有点小模糊,于是自己动手码代码做实验,然后又在网上翻了一些资料,对于字符串与数字、数字与数字、字符串与字符串之间数字的比较进行啦一些较为深入的了解,在某些地方,理解的有欠妥的地方,还...

chixin4603的博客 2784

详解一下 javascript 中的比较

今天在 JS笔试题 被 @公子 给AT了,遂想起之前要写的一篇文章,javascript 中蛋疼的比较运算。 翻译自:http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3 11.9.3 抽象相等比较算法 比较运算 x==y, 其中 x 和 y 是值,产生 true 或者 false。这样的比较按如下方式进行: 若 Typ

161

js中的比较

console.log(null > 0); // false console.log(null < 0); // false console.log(null == 0); // false console.log(null >= 0); // true console.log(null <= 0); // true 先看看 ...

chenlunju的专栏 248

JS中的this指向情况汇总

对于我们开发人员来说,this这个关键字可以说是再熟悉不过了,几乎所有主流的程序开发语言都带有this关键字。今天我们来说说在JavaScript中的this指向都有哪些情况(这也是面试中常常会问到的问题)。 JS中的this指向对于刚刚学习这门的语言的同学来说,有时往往会让人感到很困惑:明明觉得自己在很多时候应该是知道this的指向的,可真正要你回答this的指向到底有哪几种情况时,又往往说...

似水流年的博客 1万+
上一篇: [译] Vue 应用的代码覆盖率
下一篇: [译] 世界比以往任何时候都更需要 Web 可访问性
云前端
博客等级 码龄17年 101粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值