坦白说, js 中的 == 比数学中的 == 更有深度, 不愧是被称为 "最糟糕的特效" 之一.
查了大量资料, 感谢前辈们. 在此, 为了温故而知新, 总结一下:
一. 记住 == 运算的规则:
(1)undefined == null, 结果是 true. 且它俩与所有其他值比较的结果都是 false.
假如你打算把一个变量赋予对象类型的值, 但是现在还没有赋值, 那么你可以用 null 表示此时的状态(证据之一就是 typeof null 的结果是 object);
相反, 假如你打算把一个变量赋予原始类型的值, 但是现在还没有赋值, 那么你可以用 undefined 表示此时的状态.
Undefined 类型和 Null 类型的都只有一个值, 即 undefined 和 null, 都是空值, 所以 undefined == null 的结果是 true 是很合理的.
在强制转换方法里面:
转换为数值类型:
Number(mix),parseInt(string,radix),parseFloat(string)
转换为字符串类型: toString(radix),String(mix)
转换为布尔类型: Boolean(mix)
也没有谁能转换成它们两者, 所以它俩与所有其他值比较的结果都是 false.
(2)String == Boolean, 需要两个操作数同时转为 Number.
(3)String/Boolean == Number, 需要 String/Boolean 转为 Number.
(2)和 (3) 中 String,Blooean,Number 三种类型是除 undefined 和 null 外的基本数据类型.
这三种两两比较都先转成 Number 再对比结果.
而 Boolean 只有两个值: true 和 false, 转换成 Number: true-->1 false-->0
栗子如下:
- // 字符串与数字的对比
- console.log('1' == 1); //true
- // 字符串与布尔值的对比
- console.log('0' == false); //true
- // 数字与布尔值的对比
- console.log(1 == true); //true
- // 数字与数字的对比
- console.log(1 == 1); //true
- // 布尔值与布尔值的对比
- console.log(false == false); //true
- // 字符串与字符串的对比
- console.log('1' == '1'); //true
- console.log('4a' == 'f'); //false
注意字符串之间的对比, 如果不是纯数字字符串, 字符串之间的对比是根据 ASCII 表数值排列, 如果第一个值相等, 对比第二个... 只要得出 ASCII 值, 后面不必再对比. 一般而言, 字符串对比两者需要一模一样才能相等.
字符串比较特殊:
- console.log(Number(null)); //0
- console.log(Number(undefined)); //NaN
- console.log(Number('')); //0
- console.log(Number(' ')); //0
- console.log(Number(0)); //0
- console.log(Number('头好晕')); //NaN
- console.log(Number('0.0')); //0
- console.log(Number('100px')); //NaN
- console.log(Number('-10')); //-10
- // 规律: Number() 只支持数字字符串, 除了空字符串, 空格字符串;
(4)Object == Primitive, 需要 Object 转为 Primitive(具体通过 valueOf()和 toString()方法).
toString()方法用来得到对象的一段文字描述; 而 valueOf()方法用来得到对象的特征值.
顾名思义, toString()方法倾向于返回一个字符串. valueOf()方法根据规范中的描述, 它倾向于返回一个数字 -- 尽管内置类型中, valueOf()方法返回数字的只有 Number 和 Date.
下表列出了对象的 valueOf()的返回值:
对象 | 返回值 |
---|---|
Array | 数组的元素被转换为字符串,这些字符串由逗号分隔,连接在一起。其操作与 Array.toString 和 Array.join 方法相同。 |
Boolean | Boolean 值。 |
Date | 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC。 |
Function | 函数本身。 |
Number | 数字值。 |
Object | 对象本身。这是默认情况。 |
String | 字符串值。 |
toString(radix)方法. 除 undefined 和 null 之外的所有类型的值都具有 toString()方法, 其作用是返回对象的字符串表示.
对象 | 操作 |
---|---|
Array | 将 Array 的元素转换为字符串。结果字符串由逗号分隔,且连接起来。 |
Boolean | 如果 Boolean 值是 true,则返回 “true”。否则,返回 “false”。 |
Date | 返回日期的文字表示法。 |
Error | 返回一个包含相关错误信息的字符串。 |
Function | 返回如下格式的字符串,其中 functionname 是被调用 toString 方法函数的名称:function functionname( ) { [native code] } |
Number | 返回数字的文字表示。 |
String | 返回 String 对象的值。 |
默认 | 返回 “[object objectname]”,其中 objectname 是对象类型的名称。 |
当一个对象与一个非对象比较时, 需要将对象转化为原始类型, 布尔类型变成数字类型.
举个栗子: console.log([''] == false); //true
(1) 首先, 两个操作数分别是对象类型, 布尔类型. 需要将布尔类型转为数字类型, 而 false 转为数字的结果是 0, 所以表达式变为:[''] == 0 , 两个操作数变成了对象类型, 数字类型.
(2) 需要将对象类型转为原始类型:
首先调用 [].valueOf(), 由于数组的 valueOf() 方法返回自身, 所以结果不是原始类型, 继续调用[].toString().
对于数组来说, toString()方法的算法, 是将每个元素都转为字符串类型, 然后用逗号, 依次连接起来, 所以最终结果是空字符串'', 它是一个原始类型的值.
此时, 表达式变为:'' == 0 , 两个操作数变成了字符串类型, 数字类型.
(3) 需要将字符串类型转为数字类型, 前面说了空字符串变成数字是 0. 于是表达式变为: 0 == 0
结果明显是 true.
再举个栗子: console.log({} == false);//false
- console.log({}.valueOf());//{}
- console.log({}.toString());//'[object Object]''
- console.log({} == false);//false
二. 补充:
1.JS 中如何确定六大数据类型?
(1)以原始类型和复杂类型而言:
原始类型 (Primitive) 包括: Undefined,Null,Boolean,Number 和 String 五种原始类型, 对象类型(Object).
(2)以 typeof 获得类型: Undefined,Function,Boolean,Number,String 和 Object.
2.js 中基本数据类型和引用数据类型的区别?
JS 基本数据类型的变量存放的是基本类型数据的实际值; 而引用数据类型的变量保存对它的引用, 即指针.
(1)JS 基本数据类型: null,undefined,number,boolean,string 比较特殊
(2)引用数据类型: function object array
如:
- var a = 11;
- var b = a;
- b = 12;
- console.log(a); //11==> a 的值不会随 b 值得改变而改变
- var c = [1,2,3];
- var d = a;
- c[0] = 2;
- console.log(d[0]) //2==> b 的值随着 a 的值改变而改, 因为他们指向同一个内存地址
3. 强制转换:
Number(mix)函数, 可以将任意类型的参数 mix 转换为数值类型. 其规则为:
(1)如果是布尔值, true 和 false 分别被转换为 1 和 0
(2)如果是数字值, 返回本身.
(3)如果是 null, 返回 0.
(4)如果是 undefined, 返回 NaN.
(5)如果是字符串, 遵循以下规则:
1, 如果字符串中只包含数字, 则将其转换为十进制(忽略前导 0)
2, 如果字符串中包含有效的浮点格式, 将其转换为浮点数值(忽略前导 0)
3, 如果是空字符串, 将其转换为 0
4, 如果字符串中包含非以上格式, 则将其转换为 NaN
(6)如果是对象, 则调用对象的 valueOf()方法, 然后依据前面的规则转换返回的值. 如果转换的结果是 NaN, 则调用对象的 toString()方法, 再次依照前面的规则转换返回的字符串值.
parseInt(string, radix)函数, 将字符串转换为整数类型的数值. 它也有一定的规则:
(1)忽略字符串前面的空格, 直至找到第一个非空字符
(2)如果第一个字符不是数字符号或者负号, 返回 NaN
(3)如果第一个字符是数字, 则继续解析直至字符串解析完毕或者遇到一个非数字符号为止
(4)如果上步解析的结果以 0 开头, 则将其当作八进制来解析; 如果以 x 开头, 则将其当作十六进制来解析
(5)如果指定 radix 参数, 则以 radix 为基数进行解析
parseFloat(string)函数, 将字符串转换为浮点数类型的数值.
它的规则与 parseInt 基本相同, 但也有点区别: 字符串中第一个小数点符号是有效的, 另外 parseFloat 会忽略所有前导 0, 如果字符串包含一个可解析为整数的数, 则返回整数值而不是浮点数值.
String(mix)函数, 将任何类型的值转换为字符串, 其规则为:
(1)如果有 toString()方法, 则调用该方法 (不传递 radix 参数) 并返回结果
(2)如果是 null, 返回 "null"
(3)如果是 undefined, 返回 "undefined"
Boolean(mix)函数, 将任何类型的值转换为布尔值:
以下值会被转换为 false:
false,"",0,NaN,null,undefined,
其余任何值都会被转换为 true.
来源: http://www.bubuko.com/infodetail-2730246.html