前言
面试的时候,你会遇到许多奇奇怪怪的问题。就好像上学的时候,你在数学课本里学习了等边三角形的三个内角都是等于 60 度,你很少能见到卷子里直接问你等边三角形的三个内角是多少度。多数情况下这个知识点会被嵌套在一个几何题里,作为一个论证依据,如果你不知道这个知识点,那就解答不出这道题。
前端面试的时候,面试官问你奇奇怪怪的问题,你可能觉得,我写业务根本用不上这些鸟东西。如果你的思想停留在这个位置,那可能你也就只能停留在切图仔这个层面。
类型转换
问:a == 1 && a == 2 && a == 3,如何让其返回 true?
看到这个问题,我一开始是不知所措的,a
若是一个常量,那么它必然某个值,为何能同时等于 3
个值。正当我百思不得其姐的时候,我再次认真的审题,a
在这条表达式中有一个动作,就是去和 1
和 2
和 3
依次做了判读是否相等,在 JS
中,两个不同类型的值在判断是否相等的时候,都会做一次转换,我们能不能控制这个转换的方法,并且返回新的值呢?我们尝试如下代码:
var a = {
toString: function() {
console.log('转换')
}
}
a == 1
// 转换
// false
a == '1'
// 转换
// false
a == {}
// false
a == []
// false
复制代码
如上述代码所示,我们重写对象 a
的 toString
方法。
- 当对象
a
和一个数字1
做比较的时候,执行了a
的toString
方法。 - 当对象
a
和一个字符串1
做比较的时候,执行了a
的toString
方法。 - 当对象
a
和一个空对象做比较的时候,未执行a
的toString
方法。
知识点:这便是 JS 的类型转换,引用类型在和基础类型做比较的时候,会先经过 toString 方法做类型转换。
所有引用类型的隐式原型下,都有一个 toString
方法,如下图所示:
那么,上述的考题就好解决了,思路大概就是,设置 a
变量为一个对象,重写对象的 toString
方法,大致如下所示:
var a = {
value: 0,
toString: function() {
return ++this.value
}
}
a == 1 && a == 2 && a == 3
// true
复制代码
每次对比的时候,都会触发 toString
方法,返回自增后的值,依次加到 3
为止,最后返回 true
。
这里穿插一个小知识,上述重写
toString
不要用尖头函数,如果使用尖头函数,函数内的this
将会指向全局window
对象,尖头函数的this
永远只想第一个包裹它的正常函数,逐级往上找,直到window
全局对象。所以上述代码如果写了肩头函数,this.value
相当于window.value
,返回undefiend
。
Object.defineProperty
如果我们将考题变种,问:a === 1 && a === 2 && a === 3,如何让其返回 true?
此时你心想,狗日的,什么乱七八糟的。没错,此时的你只能以不变应万变,那就是夯实自己的 JS 基础。变种考题和之前的区别在于,用了严格模式的 ===
,它是不会触发类型转换调用 toString
。
解决上述问题。可以上 getter
,getter
的作用就是当你访问变量的时候,会被拦截。如上述表达式,当执行到 a
的时候,其实就访问了 a
变量,那么我们引出 Object.defineProperty
,代码如下:
var value = 0
Object.defineProperty(window, 'a', {
get() {
return ++value
}
})
a === 1 && a === 2 && a === 3 // true
复制代码
第一次对比 a === 1
此时访问了 a
变量,get
方法执行,返回 1
。以此类推,最后 a
为 3
。
总结
这些题目不是重点,重要的是这些题目背后所带出的 JS
知识。你可能觉得我平时业务开发基本上用不上这些知识点,但是真到了写一些上层架构的时候,这些基础知识,将会是你获取更多机会和财富的敲门砖,我不敢保证给大家出一个系列专栏,尽量保持周更吧,平时是真滴忙。
往期好文推荐
打通任督二脉的前端环境变量 — env 点赞数? 228
Vite 2.0 + React + Ant Design 4.0 搭建开发环境 点赞数? 385
面不面试的,你都得懂原型和原型链 点赞数? 593
Vue 3 和 Webpack 5 来了,手动搭建的知识该更新了 点赞数? 521
换一个角度分析,网页性能优化 点赞数? 200
你好,谈谈你对前端路由的理解 点赞数? 625
以前我没得选,现在我只想用 Array.prototype.reduce 点赞数? 588
无处不在的发布订阅模式 —— 这次一定 点赞数? 164
聊聊 JSX 和虚拟 DOM 点赞数? 110