JS中捉摸不透的==(宽松等于)

首先来看一个有意思的面试题:

if(a == 3 && a == 4){//...
}

第一眼看到这个面试题我是拒绝的,这个等式根本不会成立,怎么会存在一个值既等于3并且还同时等于4呢?根本不可能。

但是在神奇的javascript中这个a是存在的。(对javascript要永远怀着一颗敬畏的心)

var i = 3;
var a = new Object();a.valueOf = function(){return i++;
}if(a == 3 && a == 4){console.log('等式成立了'); // 打印了
}

简单一看这个面试题有点故弄玄虚,谁会这样写代码?(我之前的想法)

但是这其中的知识点很有用,并且不是很好掌握。

其中的主要知识点就是宽松等于(==)涉及到的隐式类型转换。在日常开发中总会被提醒尽量不要使用宽松等于,在相等比较时尽可能的使用严格等于。但是为什么呢?其实通过上面的面试题就可以看出来,宽松等于太神奇了(晦涩难懂,莫名其妙,坑太多),当然这是对于不太了解宽松等于类型转换的我来说的。接下来则会不自量力的尽力来解释一下类型转换和宽松等于。

首先对于 == 和 === 的区别常被解释为 == 并不检查数据类型,=== 检查数据类型。但是这个说法并不完全正确。相对正确的说法是 == 允许数据进行类型转换而 === 并不允许。第一种说法貌似是 === 做了更多的事情,但事实却不是这样的。

== 的几种情况分别是

  1. 两个值类型相同则比较值

    1.1 NaN不等于自身

    1.2 +0 等于 -0

    1.3 两个对象指向同一个值则相等(不发生强制类型转换)

    1.4 === 对于对象的比较同1.3

  2. 数字和字符之间的比较

  3. Boolean和其他之间的比较

  4. 对象和非对象之间的比较

#数字和字符串之间的比较

一个String类型值和一个Number类型值之间比较则将String类型值按照 转换为Number表转为Number类型。

var a = '1';
var b = 1;console.log(a == b); // true 字符‘1’被转换成了数字1再作比较则相等
console.log(a === b); // false 并没有对字符'1'数据类型转换,数据类型不同则不相等

Boolean类型值和其他类型值之间的比较

一个Boolean类型值和一个其他类型值之间比较则首先将Boolean类型值转换为Number类型,true是1而false是0。

var a = true;console.log(a == 1); // true转换成了数字1再作比较则相等

Object和其他类型值之间的比较

一个Object类型值和一个其他类型值之间比较则将Object类型值按照如下步骤转化:

  1. 该对象如果有valueOf方法则调用该方法
  2. 若该valueOf的返回值是基本类型则用作比较
  3. 若valueOf的返回值不是基本类型则调用toString方法
  4. 若toString方法返回基本类型值则用作比较
  5. 若toString返回值不是基本类型则报错
var a = {valueOf: function(){return 1;},toString: function(){return 2;}
};console.log(a == 1); // true 调用a.valueOf获得返回值再比较
var a = {valueOf: function(){return '1';},toString: function(){return 2;}
};console.log(a == 1); // true

以上代码当对象a和数字1作比较调用valueOf方法获得字符串‘1’,这时变成了字符串’1’和数字1作比较,根据字符串和数字比较的规则,将字符串转换成数字等到数字1,然后两个数字1作比较得出相等。

当没有valueOf方法或者valueOf方法不返回基本类型值的时候则调用toString方法。

var a = {toString: function(){return 1}
};console.log(a == 1); // true

到这里开篇的那道面试题则不难理解了,宽松等于中对象和其他类型比较时涉及到了隐式强制类型转换,首先会调用valueOf方法,如果有必要还会调用toString方法来获取值来进行比较。

Null和Undefined之间的比较

在宽松等于比较中Null类型值只和自身还有Undefined类型值相等。

console.log(null == undefined); // trueconsole.log(null == false); // falseconsole.log(undefined == false); // falseconsole.log(null == ''); // falseconsole.log(undefined == ''); // falseconsole.log(null == 0); // falseconsole.log(null == ''); // false

几个宽松等于的坑

console.log(![] == []); // true
// 取反的优先级高于 ==,所以![]转为false,false转为0,[]调用valueOf得到[],所以调用toString得到‘’,然后''转为0,得到相等console.log(false == []); // true 
//false转为 0,[]根据上面的步骤转为0,得到相等"0" == false; // true 注意"0"并不是假值但是这里却是相等的,因为 false 转为 0,变成了数字和字符比较,字符串"0"转为了数字0得到相等

宽松等于中值a与Boolean作比较并不是比较值a是否为真或假,而是值a与转换过后的Boolean值(0或1)作比较。

参考

你不知道的javascript(中卷)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362226.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vue脚手架的使用

安装:1.全局安装脚手架:cnpm install -g vue/cli 使用:2.新建文件夹,在当前目录执行命令 vue create "项目名称"3.配置:选择Manually select feautures--》空格选择Babel和CSS Pre-procesors--》选择Sass/SCSS(with dar…

Akka笔记–演员介绍

过去做过多线程的任何人都不会否认管理多线程应用程序有多么艰辛和痛苦。 我说管理是因为它一开始很简单,一旦您开始看到性能改进,它就会变得非常有趣。 但是,当您发现没有一种简单的方法可以从子任务中的错误或难以发现的僵尸错误中恢复时&a…

浏览器的同源策略与跨域

本文所有案例在本地址都可找到:https://github.com/dancingZhou/sameOrigin/tree/dev 什么是同源策略 两个页面地址中的协议、域名和端口号一致,则表示同源。 例如该地址 https://www.google.com 和以下地址对比 地址同源原因http://www.google.com否…

poj 1185

经典状态dp 代码&#xff1a; #include<iostream> #include<fstream> #include<cmath>using namespace std;int n,m;char map[101][11];int state[101][1024]; int num[101]; int value[1024]; int maxx;int ok(int s,int t){int i,j,k;for(i0;i<m;){jt&…

day03 爬虫

今日内容&#xff1a;一 爬虫原理二 Requests请求库一 爬虫原理1.什么是互联网&#xff1f;指的是由一堆网络设备&#xff0c;把一台台的计算机互联网到一起称之为互联网。2.互联网建立的目的&#xff1f;互联网建立的目的是为了数据的传递以及数据的共享。3.什么是数据&#x…

Java英雄:丹·艾伦

“ Java英雄 ”系列休息了很长时间。 老实说&#xff0c;我想即使有很多人想在这里收录&#xff0c;它也可能会以虚无收场。 其中之一是丹。 我第一次要求他捐款已经将近一年半了&#xff0c;与此同时发生的一切&#xff0c;让我不再有任何答案就让我安心了。 但是以下内容在Ja…

yearProgress.vue

1 <template>2 <div class"progressbar">3 <el-progress :text-inside"true" :soke-width"18" :percentage"percent" status"exception"></el-progress>4 <p>{{year}}年已经过去了…

group by rollup

首先引用ITPUB上的总结&#xff1a; rollup(a,b,c)----------------> 从右到底递减汇总>group by a,b,c (减0次)UNION ALL>group by a,b (减1次)UNION ALL>group by a (减2次)UNION ALL>group by null(全部汇总) (全部减掉)移动了4次&#xff0c;所…

Java-Class-I:java.util.List

ylbtech-Java-Class-I&#xff1a;java.util.List1.返回顶部 1.1、import java.util.ArrayList;import java.util.List; 1.2、List<Integer> newList new ArrayList<Integer>();newList.add(3); 2、 2.返回顶部1.1、import java.util.*;public class Test{public …

JS中编码的三种方法

在开发中经常需要对用户输入的数据进行编码然后才能通过HTTP请求发送给后台&#xff0c;或者对传递过来的数据进行解码。在JS中原生提供了三种编码/解码方式&#xff0c;分别是 encodeURI、 encodeURIComponent和 escape。 为什么URL需要编码&#xff1f; URI设计要求可移植&…

一个类加载的谜团解决了

面对一个好老问题 我在应用程序服务器上遇到一些类加载问题。 这些库被定义为Maven依赖项&#xff0c;因此被打包到WAR和EAR文件中。 不幸的是&#xff0c;其中一些也已安装到应用程序服务器中&#xff0c;但版本不同。 启动应用程序时&#xff0c;我们遇到了与这些类型的问题相…

vue 隐藏滚动条

element-ui隐藏组件scrollbar&#xff1a; <el-scrollbar style"height:100%"> </el-scrollbar>真正的隐藏滚动条代码在这里&#xff1a;.el-scrollbar__thumb {display: none;}.el-scrollbar__wrap {overflow-x: hidden;overflow-y: auto;}更多专业前端…

希望菜鸟通过博客园的记录和学习,成为一个可以能把自己想发实现的小程序员!...

我是一个学习电气自动化专业的毕业生&#xff0c;工作多年&#xff0c;接触过c语言、vb、单片机、PLC、linux&#xff0c;希望菜鸟通过博客园的记录和学习&#xff0c;成为一个可以能把自己想发实现的小程序员&#xff01; 生活和工作中有许多自己的表格和统计数据&#xff0c;…

获取DOM元素方法小结

在开发中不可避免的需要操作DOM&#xff0c;现在就来总结一下原生的获取DOM的API。 getElementById() 该方法是最常用的通过元素的id属性来获取DOM元素的API&#xff0c;返回一个DOM元素。 <body><div id"div">我是div</div><script type&qu…

推荐:个人时间跟踪工具 ManicTime

在《个人管理 &#xff0d; 目标管理之前&#xff0c;你会时间管理吗》中我介绍的时间管理三阶段之一“对时间的实际去处进行记录”时说过现在有很多时间管理工具&#xff0c;也有人希望我介绍一下我使用的工具&#xff0c;那么我就利用中午休息时间&#xff0c;马上给大家介绍…

Java和甜蜜的科学

当您使用Java进行开发已有15年并且同事要求您帮助他们调试空指针异常时&#xff0c;您不会感到惊讶。 通常&#xff0c;很明显什么是null&#xff0c;唯一要做的就是找出原因。 有时会有些困难&#xff0c;因为有人创建了一系列取消引用的对象。 前几天&#xff0c;我遇到了一…

SQL Server 2005怎样进行性能排错

很少会有偶然的性能下降。设计不良的数据库或工作负载配置不正确的系统会经常导致性能问题。管理员需要能预先阻止或最小化问题的影响&#xff0c;当管理员遇到问题时&#xff0c;应该诊断问题并采取正确操作来修复问题。本文提供了按部就班的指导&#xff0c;通过使用可用的工…

AcWing 207. 球形空间产生器 (高斯消元)打卡

有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。 现在&#xff0c;你被困在了这个n维球体中&#xff0c;你只知道球面上n1个点的坐标&#xff0c;你需要以最快的速度确定这个n维球体的球心坐标&#xff0c;以便于摧毁这个球形空间产生器。 输入格式 第一行是一个整数…

jQuery中的ready

基于jQuery v1.8.3 在js与DOM交互之前要确保DOM已经加载构建完成&#xff0c;在jQuery中都是使用 (fn)或者(document).ready(fn)来确保自己写的代码在DOM构建完成之后执行。 那么jQuery的ready事件内部怎么实现的呢&#xff1f; 通过阅读源码&#xff08;line:842 ~ 898&…

JVM PermGen –您在哪里?

这篇文章介绍了JVM内存结构的一些基础知识&#xff0c;并快速窥视了PermGen&#xff0c;以了解自Java SE 8出现以来它已消失的地方。 裸基础 JVM只是系统上运行的另一个进程&#xff0c;魔术始于java命令。 像任何OS进程一样&#xff0c;它需要内存才能运行。 记住– JVM本身是…