let a = [] == []
let b = [] === []
let c = [] == ""
let d = [] == ![]
一:JavaScript中==与===的区别及数据类型详解
==(相等):此操作符执行类型转换以比较值,意味着如果两边的数据类型不同,它会尝试将其转换为相同的类型再进行比较。这种特性虽然提供了灵活性,但也可能导致意料之外的结果,因为比较时可能会忽视原始类型信息。
===(严格相等):相比之下,严格相等不仅要求两边的值相等,还要求它们的类型完全一致。这意味着,即使两个看似等价的值属于不同类型,===也会返回false。这一特性使得它成为代码中更推荐使用的比较方式,因为它能避免因类型转换引起的混淆。
二:JavaScript中数据类型分类
基本数据类型(Primitive Types):包括String(字符串)、Number(数字)、Null、Undefined、Boolean(布尔值),以及Symbol(ES6引入)。
复杂数据类型(Reference Types)或称为对象类型:主要包括Object、Array、Function,以及BigInt和Date等。这些类型存储在堆内存中,并通过栈中的引用访问。
三:内存分配:栈与堆
栈:栈会自动分配内存空间,会自动释放,存放基本类型,简单的数据段,占据固定大小的空间。
堆:动态分配的内存,大小不定也不会自动释放,存放引用类型,指那些可能由多个值构成的对象,保存在堆内存中,包含引用类型的变量,实际上保存的不是变量本身,而是指向该对象的指针。
栈:所有在方法中定义的变量都是放在栈内存中,随着方法的执行结束,这个方法的内存栈也自然销毁。
堆:堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(参数传递)。创建对象是为了反复利用,这个对象将被保存到运行时数据区。
四:面试题解释
let a = [] == []
这里使用到了 == ,他会将两个值进行转化成相同的类型,然后在比较他们的值,但是,即使两个空数组具有相同的结构,它们仍然是不同的对象,因此类型转换后它们的引用地址也是不同的。
所以返回值为:false
let b = [] === []
这里使用了严格等于操作符,它不会进行类型转换,而是直接比较操作数的值和类型。
由于两个空数组虽然具有相同的结构,但它们是不同的对象,因此它们的引用地址也是不同的。
所以返回值为false
let c = [] == ""
这里一个操作数是空数组,另一个是空字符串。
在双等于操作中,它们会被转换为相同的类型,然后比较。由于空数组转换为字符串后是空字符串,它们的值相等。
所以返回值为:true
let d = [] == ![]
这里的操作数是一个空数组和一个逻辑非运算 ![]。
![] 将数组转换为布尔值,由于数组是真值,所以取非后为 false。
在双等于操作中,数组和布尔值会被转换为数字,空数组会被转换为 0,而布尔值 false 会被转换为 0。
所以返回值为:true