前言与说明
本文首发于 我的博客 。前几天社团学长发布的一道JS题,在经历一番折腾后终于想通了。后来又了解到这原来是一道前端面试题,特此记录一下。
---------------更新----------------
看到不少小伙伴评论说这个没必要没有实际用处什么的,这里说明以一下。其实这里是就一个JS面试题展开的思考,在分析过程中,会发现其实蕴含了很多JS原理的,重点是对问题的分析所得出的结论。
---------------分界----------------
问题
先说说 南昌大学家园工作室 学长发布的一道题。当 a 是什么的时候,判断条件会成立?输出的 a 又是什么?
var a = ???;
if(a == 1 && a == 12){
console.log(a);
}
分析
首先可以肯定 a
不是字面量(比如数值或字符串),因为 a
不能同时等于多个值。
然后想到对象,如果 a
是对象,则在执行 ==
比较的时候,会进行 valueOf
方法(或 toString)。
由此我们想到可以用自定义 valueOf
或 toString
方法来覆盖其原型方法。
var a = {
i: 1,
valueOf: function() {
if(this.i === 1){
this.i++; // i 自增为 2,之后再次判断这里就不会执行了
return 1;
} else {
return 12; // 第二次 == 比较,返回 12
}
}
}
if(a == 1 && a == 12) {
console.log(a); // { i: 2, valueOf: [Function: valueOf] } 注意 i 已经自增为 2 了
}
另一种思考
a
可以等于多个值,又可以想到数组;a
也不可能同时等于多个不同的值,而在进行==
比较的时候,数组会由join
方法转换成字符串,因此可以改写join
方法。(不太符合题意)
var a = [1,12];
a.join = a.shift; // 其实这已经不符合题意了
if(a == 1 && a == 12 ) {
console.log(a); // [ join: [Function: shift] ] 数组的shift方法会删除数组第一个元素
}
类似问题
这是原来那一道面试题。
var a = ???;
if(a == 1 && a == 2 && a == 3) {
console.log(a);
}
其实方法是类似的
var a = {
i: 1,
valueOf: function() {
return this.i++;
}
}
if(a == 1 && a == 2 && a == 3) {
console.log(a); // { i: 4, valueOf: [Function: valueOf] } 输出 a 对象,注意 i 的值
}
原文链接
JS中数据的隐式转换之谜mphy.gitee.io参考链接
Object.prototype.valueOf()
Object.prototype.toString()
JavaScript join()
JavaScript 数组方法