[] == ![] 为什么是 true
-
如果等号两边类型相同
- 对象: 仅当两边的操作数引用同一个对象时返回
true
const obj = { a: 1 }; obj == obj; // true obj == { a: 1 }; // false- 字符串:仅当两个操作数具有相同的字符且顺序相同时返回
true
"abc" == "abc"; // true "abc" == "cba"; // false- 数字:如果两个操作数的值相同,则返回
true。+0和-0被视为相同的值。如果任何一个操作数是NaN,返回false;所以,NaN永远不等于NaN
9 == 9; // true +0 == -0; // true 9 == NaN; // false NaN == NaN; // false- 布尔:仅当操作数都为
true或都为false时返回true。
true == true; // true false == false; // true true == false; // false- 符号:仅当两个操作数引用相同的符号时返回
true。
const symbol = Symbol("key"); symbol == symbol; // true symbol == Symbol("key"); // false- 大整数:仅当两个操作数的值相同时返回
true。
- 对象: 仅当两边的操作数引用同一个对象时返回
-
如果等于一边存在
undefined或null,那么另一边 一定也要是undefined或null,否则为false
undefined == undefined; // true
null == null; // true
undefined == null; // true
null == 9; // false
null == "9"; // false
- 如果等号两边存在一边对象,一边原始值
将对象转换为原始值 (隐式类型转换)
- 如果等号两边都是原始
- 如果类型相同 则参考类型相同比较
- 如果其中一个操作数是符号(Symbol)而另一个不是,返回
false。 - 如果其中一个布尔,另一个不是布尔,将布尔值转换成数字
- true -> 1
- false -> 0
- 如果其中一个数字,另一个是字符串,将字符串转换为数字
- '12.34' -> 12.34
- '12.a34' -> NaN
回归正题
[] == ![]
第一步 显式类型转换
![] = false
原式 = [] == false
第二步 进入 第三条比较规则
将对象转换为原始值
[] = ''
原式 = '' == false
第三步 进入 第四条比较规则
布尔转换成数字
原式 = '' == 0
第四步 进入 第四条比较规则
字符串换成数字
原式 = 0 == 0
第五步 进入 第一条比较规则
两边类型相等 且都为数字 且 没有NaN 且 操作数相等
则 返回 true
连等赋值 a.x = a = {n:2}
var a = { n: 1 };
var b = a;
a.x = a = { n: 2 };
console.log(a.x);
console.log(b.x);
console.log(a);
console.log(b);
// 打印什么
需要了解的前置知识 运算符优先级
图解
- var a = { n: 1 } 给a在堆中开辟了一块内存空间
- var b = a 将b的指针指向了堆内存中与 a 相同的内存空间
- a.x = a = { n: 2 }
优先级.最高
优先执行 a.x
- 赋值操作 从右 到左执行
a = {n: 2}
a指向一块新的内存空间
- 最后 执行 a.x = {n: 2}
a.x即 b.x
搞一个简称
地址1: {n: 1, x: 箭头}
地址2: {n: 2}
a 现在指向的是 地址2
b 现在指向的是 地址1
a.x 因为地址2中没有x 所以是 undefined
b.x 指向地址2
结尾
草率结尾