JS 迷惑题大赏
点击答案,即可查看答案。
1、对象的引用
let a = {n : 1};
let b = a;
a.x = a = {n: 2};
console.log(a.x) // ?
console.log(b.x) // ?
答案:
输出:a.x => undefined b.x => {n:2}
解释:
1. a 被重新赋值为 { n:2 },没有 x 属性,所以输出 undefined;
2. a.x 是给原来 a 指向的对象即 { n:1 }添加了 x 属性,属性值为 { n:2 }。因为 b 也指向这个对象,因此 b.x 输出 { n:2 }
2、对象的引用Ⅱ
let a = { n: 1 };
let b = a;
b.n = a.f = { n: 2 };
console.log(a); // ?
console.log(b); // ?
答案:
输出:
// a
{ n: { n: 2 }, f: { n: 2 } }
// b
{ n: { n: 2 }, f: { n: 2 } }
解释:
a添加了 f 属性,属性值为:{ n:2 };因为b和a指向同一个对象,所以,b也有了这个属性;同样的,b修改了n属性值,a也会跟着改变
3、push 做了什么
var obj = {
"2" : 3,
"3" : 4,
"length" : 2,
"splice" : Array.prototype.splice,
"push" : Array.prototype.push
}
obj.push(1)
obj.push(2)
console.log(obj)
答案:
输出:[empty, empty, 1, 2]
解释:
1. push 方法相当于设置 obj[obj.length] = push的值,然后让 obj.length += 1。因为存在 splice 方法,所有输出形式是一个类数组,且长度为 4
4、声明函数的立即执行
var b = 10;
(function b(){
b = 20;
console.log(b) // ?
})();
答案:
输出:function b(){ ... }
解释:
在立即执行函数内部访问未经声明的变量,会优先查看是否是当前函数的函数名,而在非匿名自执行函数中,函数名为只读属性,无法被修改。
**变化一番:**
var b = 10;
(function b(){
console.log(b) // ?
b = 5
console.log(window.b) // ?
var b = 20
console.log(b) // ?
})()
答案:
输出:undefined 10 20
解释:
因为函数内部有 var 声明,b变量提升,所以第一个b输出 undefined,第二次输出访问 window 上的b,输出 10,第三次输出函数中的 b,此时b已经赋值,故输出 20
5、相等的奥义
[] == ![] // ?
答案:
输出:true
解释:
在JS中,两个等号的比较会优先转换值类型为统一类型,再进行值的比较。转换规则如下:
①、如果比较值有一个是布尔值,则在比较相等性之前先将比较的值转换为数字类型——false转换为0,而true转换为1;
②、如果比较值一个是字符串,另一个是数字,在比较相等性之前先将字符串转换为数字
③、如果比较值一个是对象,另一个不是,则调用对象的valueOf()方法,返回值按照前面的规则进行比较
上述表达式即:[] == false,使用①法则,二者变为Number类型都为 0,所以是相等的。
**雪上加霜:**
var a = [0];
if(a){
console.log(a == true);
}else {
console.log("what the fuck!");
}
// ?
答案:
输出:false
解释:
因为a是一个数组,转换为布尔值结果为 true,因此进入 if 语句条件为真的执行体;比较时使用规则 ①,[0] 转换为数字为 0, true 转换为数字为 1,因此不相等,返回false。
6、短路与三元
1 || 2 && 3; // ?
1 || 1 ? 2 : 3 // ?
答案:
输出:1 2
解释:
短路语句中 || 会优先输出真值,1转换为布尔值即为true,因此输出 1;第二个语句中三元运算式会根据前面的短路语句的返回值进行判断,1 为 true,所以返回 2
7、Math.min
与Math.max
Math.min() < Math.max() // ?
答案:
输出:false
解释:
因为 Math.min 不带参数的结果输出为 Infinity,而 Math.max 不带参数的结果输出为 -Infinity
8、不良代码书写习惯
function f()
{
return {
a: 10
}
}
function fn()
{
return
{
b: 10
}
}
console.log(f()); // ?
console.log(fn()); // ?