javascript中的相等操作符(==与===区别)

1.前言

我们在编程的过程中,经常会遇到判断两个变量是否相等的情况,ECMAscript提供了两种相等操作符”==”和”===”来判断,这两种操作都会返回一个boolean值。一般来说,我们把”==”称之为相等,称”===”为全等。当两相比较的两个变量数据类型一致时,情况比较简单,而当操作符两边的变量类型不一致,甚至其中的某个变量是对象时,情况就比较复杂了,下面分别介绍当操作数类型不同时运算结果会怎么样。

2.全等操作符 “===”

全等操作符”===”的情况相对来说比较简单。当用全等操作符”===”来判断时,首先检查操作符两边操作数数据类型是否一致,若不一致,则直接返回false,否则,才进行下一步判断。如果是两个boolean的比较,则”===”两边必须同为true或同为false,才可以返回true,否则返回false.若两相比较的是数字,那么只有当这两个数字大小相等时才会返回true,否则返回false。如果要比较的两个变量是字符串,先比较两个字符串的长度length是否相等,如果长度不一样,则返回false,如果相等,则从两个变量的第一个字符开始比较是否相等,一直比较到最后一位,如果其中的某一位不想等,则返回false,否则返回true,(注意:字符串的比较是不会忽略空格的,所以在比较两个字符串是否相等时,为确保安全,应该先去除空格,然后把两个字符串同转为大写或者小写之后再进行比较)。而null只有在null===null的情况下才会返回true,其它情况都返回false,同样,undefined只有在undefined===undefined的情况下才会返回true,否则返回false。如:

true === 1    //false
"1" === 1    //false

//boolean的比较
true === true  //true
true === false  //false

//string的比较
"hello" === "helloworrld" //false
"hello" === "world" //false
"hello" === " hello" //false
"hello" === "hellO" //false
"hello" === "hello" //true

//number的比较
1 === 1  //true
1 === 1.0 //true
1 === 1.2 //false

//null和undefined的比较
undefined === undefined  //true
null === null       //true
undefined === null    //false,两者在"=="时才返回true

如果进行”===”比较的两个操作数不是基本类型值,而是两个对象,这时候判断依据就是,判断这两个变量是否是”同一个”对象

var a,b,c;
a = b = {
	name : '柳轻侯',
	city : '南京'
};
c = {
	name : '柳轻侯',
	city : '南京'
};
a === b   //true
a === c   //false

两个对象仅仅”长得一样”是不够的,a和c都是Object实例,且两者拥有相同的属性和值,可是这两个却不是”同一个”对象,因为实际上a和c指向了两个不同的实例,所以这两个对象是不全等的。而a和b却是指向了同一个对象,换个说法,a和b是同一个对象的不同别名,他们实际上指向的对象是完全相同的,所以a === b。”!==” 与 “===” 比较规则一样,在此不再赘述。

3.相等操作符”==”

全等操作符在进行判断的时候,如果两个变量的类型不同,则直接返回false,而与此不同,”==”相等操作符在判断的时候,如果两个变量的类型不同,则会做一个隐式的类型转换,把要比较的两个值转化为相同的类型再做比较,那么这种转化规则是怎么样的?

在转化不同数据类型时,相等和不等操作符遵循下面的基本规则

  • 如果其中一个操作数是是boolean值,则在比较之前会先将boolean值转化为number值,true转化为1,false转为0;
  • 如果其中一个操作数是string类型,而另一个是number类型,则在比较之前先将string类型转化为number类型再进行判断;
  • 在比较之前,undefined和null是不会转为其他值进行比较的;
  • 如果其中一个操作数是对象,而另一个是基本类型值,则在比较之前先将对象转为基本类型值,然后再依据前面的规则进行后续的比较;

两个操作数在比较时遵循下列规则

  • undefined和null是相等的,即:undefined == null;
  • 如果有一个操作数是NaN,那么返回false,即使两个操作数都是NaN,也会返回false;
  • 如果两个操作数是对象,则比较规则跟”===”的比较规则是一样的,除非这两个操作数是同一个对象,则返回true,否则返回false;

此处需要注意的是,NaN == NaN是返回false的,NaN意思是 not a number,也就是说该操作数是一个非数字,这个非数字是不确定的,它的值是未知的,甚至可能根本就不能用javascript的语法表示出来,这样一个未知量是不能用来进行特定比较的,两个未知的东西,如果不能确定它的值是什么,当然不能说 NaN == NaN。那么既然不能用”==”来比较,我们怎么去判定一个变量是不是NaN呢 ,既然不能用相等来判定,那么不妨反其道而行之,用”!=”来判定,判定一个变量是否不等于NaN。比如:

//如果需要判定一个变量是不是NaN,可以如下
//a是你需要判定的变量
if((typeof a === "number") && a != NaN ){  //此处需要注意,NaN也是number类型
	//TODO
}

4.常见比较情况及其结果

null == undefined  // true
"NaN" == NaN    // false
5 == NaN      // false
NaN == NaN     // false
NaN != NaN     // true
false == 0     // true
true == 1      // true
true == 2      // false
undefined == 0   // false
null == 0      // false
"5" == 5      // true

5.典型例题解析

![] == [] //true

这是一道比较容易令人困惑的题,按照正常的思维模式,对一个操作数逻辑取反,跟这个操作数本身的值是相对的,如果这个操作数本身的值是true,那么取反之后就是false,反之,如果这个操作数的值是false,那么对其逻辑取反之后就是true,无论如何也不会是同一个值,可是事实上却是![] == []。首先,![]的值是false,因为这里[]被当成了一个数组的实例,是一个对象,而对象都是真值,对其取反,得到一个假值,也就是false。其次看等号右边,[]是一个对象,要将其转为基本类型值,会先调用数组的valueOf方法,而数组的valueOf方法返回数组本身,没有得到一个基本值,这时候要继续调用数组的toString方法,得到一个””空字符串,所以这时候也就变成了false == “”是否为真的问题了,而根据前面的规则,如果有一个操作数为boolean值,会将其转为数值,false转化为0。进而,问题转化为0 == “”是否为真值的问题,当number和string比较时,会将string转为number,而””会转为0。最后,问题变演化成了0 == 0是否为真值,毋庸置疑,结果是true。这里要注意的就是![],它被当成了一个整体的逻辑值,是直接对对象进行取反,是一个假值,而不是先把[]转化为基本值再取反

6.小结

“==”在比较不同类型值得时候会进行隐式的类型转化,而”===”不会转化,全等一定相等,相等却不一定全等,这是一个充分不必要条件。undefined和null相等而不全等,且在相等比较的时候不会转化为其他类型的值。NaN是不等于NaN 的,要判断某个变量是不是NaN,要用”!=”。对象和非对象在进行比较的时候会先转为基本类型值然后再根据上面的规则进行比较。

7.参考资料

《javascript高级程序设计》
《javascript权威指南》

(0)

相关推荐

  • JS之相等操作符详解

    1.相等 == 和不相等 != 先转换操作数再比较相等性 在转换不同的数据类型时,相等和不相等遵循以下规则: 1.1 如果有一个操作数是布尔值,则在比较相等性前先将其转换为数值---false转换为0,true转换为1; 1.2 如果一个操作数是字符串,另一个操作数是数值,则在比较相等性前将字符串转换为数值 1.3 如果一个操作数是对象昂,另一个不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则比较 1.4 null和undefined是相等的 1.5 在比较相等性之前,

  • JavaScript中的相等操作符使用详解

    ECMAScript 中的相等操作符由两个等于号 ( == ) 表示,如果两个操作数相等,则返回 true. 相等操作符会先转换操作数(通常称为强制转型),然后比较它们的相等性. 在转换不同的数据类型时,相等操作符遵循下列基本规则: 1. 如果有一个操作数是布尔值,则在比较相等性之前,将其转换为数值: 2. 如果一个操作数是字符串,另一个操作数是数值,在比较之前先将字符串转换为数值: 3. 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf() 方法,用得到的基本类型值按照前面

  • 判断JavaScript中的两个变量是否相等的操作符

    1.为什么要判断? 可能有些同学看到这个标题就会产生疑惑,为什么我们要判断JavaScript中的两个变量是否相等,JavaScript不是已经提供了双等号"=="以及三等号"==="给我们使用了吗? 其实,JavaScript虽然给我们提供了相等运算符,但是还是存在一些缺陷,这些缺陷不符合我们的思维习惯,有可能在使用的时候得到一些意外的结果.为了避免这种情况的出现,我们需要自己函数来实现JavaScript变量之间的对比. 2.JavaScript等号运算符存在哪

  • javascript中的相等操作符(==与===区别)

    1.前言 我们在编程的过程中,经常会遇到判断两个变量是否相等的情况,ECMAscript提供了两种相等操作符"=="和"==="来判断,这两种操作都会返回一个boolean值.一般来说,我们把"=="称之为相等,称"==="为全等.当两相比较的两个变量数据类型一致时,情况比较简单,而当操作符两边的变量类型不一致,甚至其中的某个变量是对象时,情况就比较复杂了,下面分别介绍当操作数类型不同时运算结果会怎么样. 2.全等操作符 &q

  • Javascript中的delete操作符详细介绍

    一.变量 说到javascript中的delete操作符,还是首先要搞清楚javascript中的变量和属性之间的关系. javascript中,变量和对象属性关系非常微妙,甚至可以很多时候会被等同起来,因为 javascript 在执行脚本之前会创建一个global对象,在浏览器中就是window对象,所有的全局变量都是这个global对象的属性,执行函数时也会创建一个activation对象,所有的局部变量都是这个activation对象的属性.这些可以大家可以去了解一下javascript

  • JavaScript中object和Object的区别(详解)

    JavaScript中object和Object有什么区别,为什么用typeof检测对象,返回object,而用instanceof 必须要接Object呢 这个问题和我之前遇到的问题非常相似,我认为这里有两个问题需要解决,一个是运算符new的作用机制,一个是function关键字和Funtion内置对象之间的区别.看了一些前辈的博客和标准,这里帮提问者总结一下. 1.new new运算符的作用是创建一个对象实例.这个对象可以是用户自定义的,也可以是带构造函数的一些系统自带的对象.如果 new

  • javascript中局部变量和全局变量的区别详解

    javascript有两种变量:局部变量和全局变量.当然,我们这篇文章是帮助大家真正的区别这两种变量. 首先,局部变量是指只能在本变量声明的函数内部调用.全局变量时整个代码中都可以调用的变量.当然,单单从字面上理解肯定是不清楚的,下面我详细的介绍下: 大家都知道,变量是需要用var关键字声明的.但是javascript中也可以隐式的使用变量,就是不用声明,直接使用.而且,千万注意,javascript把隐式声明的变量总是当成全局变量来使用的. 例如: 复制代码 代码如下: function my

  • JavaScript中undefined和null的区别

     JavaScript中undefined和null的区别 JavaScript两个表示"无"的值:undefined和null.我在平时只是null用的多一点,undefined只是在报错中经常遇到.下面针对这两个数据类型的异同做一下详细的比较. 1.undefined和null在if语句中,都会被自动转为false,相等运算符直接报告两者相等. !null==!undefined==true 2.null表示"没有对象",即该处不应该有值.典型用法是: (1)

  • JavaScript中click和onclick本质区别与用法分析

    本文实例讲述了JavaScript中click和onclick本质区别与用法.分享给大家供大家参考,具体如下: 原生javascript的click在w3c里边的阐述是DOM button对象,也是html DOM click() 方法,可模拟在按钮上的一次鼠标单击. button 对象代表 HTML 文档中的一个按钮.button元素没有默认的行为,但是必须有一个 onclick 事件句柄以便使用. 语法:buttonObject.click() <html> <head> &l

  • javascript中call()、apply()的区别

    call().apply()的区别: 相同点: 1.call()和apply()都可以用来间接调用函数,都可以显式调用所需的this.即,任何函数可以作为任何对象的方法来调用. 2.两个方法都可以指定调用实参. 区别: call()和apply()的基本区别:在于将参数传递给函数. call():使用其自有的实参列表作为函数的参数: apply():要求以数组的形式传入参数. function track(o,m){ var original =o[m]; o[m] =function( ){

  • JavaScript中callee和caller的区别与用法实例分析

    本文实例讲述了JavaScript中callee和caller的区别与用法.分享给大家供大家参考,具体如下: 1.callee 在函数的内部,有两个特殊的对象:arguments和this.其中arguments是一个类似数组的对象,包含着传入函数的所有参数. 虽然arguments的主要用途是保存函数参数,但这个对象有一个属性--callee,该属性是一个指针,指向拥有这个arguments对象的函数 所以callee的作用就是来指向当前对象 看一个阶层函数的例子就会明白他的用途了: /* *

  • JavaScript中toLocaleString()和toString()的区别实例分析

    本文实例讲述了JavaScript中toLocaleString()和toString()的区别.分享给大家供大家参考,具体如下: <javascript高级程序设计>解释: "toLocaleString()返回对象的字符串表示,该字符串与执行环境的地区对应:toString()返回对象的字符串表示:" 感觉还是不太好理解......来看几个实例: 字符串: var a = 6666; a.toLocaleString(); //"6,666" a.t

  • javascript中call,apply,bind的区别详解

    在JS中,这三者都是用来改变函数的this对象的指向的,他们有什么样的区别呢. 在说区别之前还是先总结一下三者的相似之处: 1.都是用来改变函数的this对象的指向的. 2.第一个参数都是this要指向的对象. 3.都可以利用后续参数传参. 那么他们的区别在哪里的,先看一个例子. var xw = { name : "小王", gender : "男", age : 24, say : function() { alert(this.name + " ,

随机推荐