为什么有了 === 还需要 Object.is()?一分钟看完!

4 阅读3分钟

JaveScript中有多种判断两个操作数是否相等的方法,一个一个介绍:

相等运算符( ==)

相等运算符对两个类型进行比较时,两个操作符类型相同时:

  • 简单类型会直接比较他们的值;
  • 引用类型会比较他们的应用地址。

两个操作数类型不同时,会进行隐式类型转换,转换规则为:

  • undefined 和 null 比较直接返回true,除了彼此,它们不会与其他任何值相等
console.log(null == undefined); // true
console.log(null == 0); // false
console.log(undefined == false); // false
  • number 和 string 比较, 会将 string 转换为 number 后再对比;
console.log('10' == 10); // true'10' 转换为数字 10
console.log('abc' == 1); // false'abc' 转换为 NaN,NaN 与 1 不相等
  • 如果其中有一个是 boolean, 会将boolean 转换为 number 后再对比;
console.log(true == 1);  // true,因为 true 转换为 1
console.log(false == 0); // true,因为 false 转换为 0
console.log(true == '1'); // truetrue 转成 1'1' 转成 1
  • 如果其中一个是 Object ,会先调用 valueOf() 方法,如果返回的不是基本类型,再调用 toString()方法再进行比较。
const arr = [10];
console.log(arr == 10); // true,数组先调用 toString() 得到 '10','10' 再转换为数字 10
  • NaN与任何值比较都返回false
console.log(NaN == NaN); // false

严格相等运算符(===)

  • 不会进行类型转换,先判断类型,类型不同直接返回false;如果类型相同在比较值。
console.log(1 === '1'); // 输出: false
console.log(1 === 1); // 输出: true

const a = [];
const b = [];
console.log(a === b); // 输出false,因为拥有不同的引用地址,值不相同。

Object.is()

ES6之前有一些特别的情况,使得 === 也不是很正确:

+0 === -0  //true
+0 === 0 //true
-0 === 0 //true

// 在判断是否为NaN时,
NaN === NaN //false
isNaN(isNaN) //true

ES6引入了Object.is()

//正确的判断
console.log(Object.is(+0, -0)); // false 
console.log(Object.is(+0, 0)); // true 
console.log(Object.is(-0, 0)); // false 

// 正确的 NaN 相等判定
console.log(Object.is(NaN, NaN)); // true 

别走!看看这道leetcode有没有思路!

Leetcode

27. 移除元素

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素。元素的顺序可能发生改变。然后返回 nums 中与 val 不同的元素的数量。

假设 nums 中不等于 val 的元素数量为 k,要通过此题,您需要执行以下操作:

  • 更改 nums 数组,使 nums 的前 k 个元素包含不等于 val 的元素。nums 的其余元素和 nums 的大小并不重要。
  • 返回 k

思路:

  • 暴力双循环(直接pass);
  • 快慢指针:一个指针i用于遍历数组,另一个指针j 用于记录不等于val的元素位置,用于交换。
/**
 * @param {number[]} nums
 * @param {number} val
 * @return {number}
 */
var removeElement = function(nums, val) {
    let j = 0;
    for(let i = 0; i < nums.length; i++){
        // 没找到目标元素之前,双指针为同一个元素,当找到之后,j 记录了要交换的位置,当 i 找到下一个不等于val的元素后,开始和 j 的位置交换。
        if(nums[i] !== val){
            nums[j] = nums[i];
            j++
        }
    }
  // 题目说了, 只需要返回删除后的元素数量,不需要管原数组最后的结果
    return j
};