前言
本文非百科全书,只专为面试复习准备、查漏补缺、深入某知识点的引子、了解相关面试题等准备。
笔者一直都是崇尚学会面试题底下涉及到的知识点,而不是刷一大堆面试题,结果变了个题型就不会的那种。所以本文和别的面经不一样,旨在提炼面试题底下的常用知识点,而不是甩一大堆面试题给各位看官。
数据类型
JS 数据类型分为两大类,九个数据类型:
- 原始类型
- 对象类型
其中原始类型又分为七种类型,分别为:
boolean
number
string
undefined
null
symbol
bigint
对象类型分为两种,分别为:
Object
Function
其中 Object
中又包含了很多子类型,比如 Array
、RegExp
、Math
、Map
、Set
等等,也就不一一列出了。
原始类型存储在栈上,对象类型存储在堆上,但是它的引用地址还是存在栈上。
注意:以上结论前半句是不准确的,更准确的内容我会在闭包章节里说明。
常见考点
- JS 类型有哪些?
- 大数相加、相乘算法题,可以直接使用
bigint
,当然再加上字符串的处理会更好。 NaN
如何判断
另外还有一类常见的题目是对于对象的修改,比如说往函数里传一个对象进去,函数内部修改参数。
function test(person) {person.age = 26person = {}return person
}
const p1 = {age: 25
}
复制代码
这类题目我们只需要牢记以下几点:
- 对象存储的是引用地址,传来传去、赋值给别人那都是在传递值(存在栈上的那个内容),别人一旦修改对象里的属性,大家都被修改了。
- 但是一旦对象被重新赋值了,只要不是原对象被重新赋值,那么就永远不会修改原对象。
类型判断
类型判断有好几种方式。
typeof
原始类型中除了 null
,其它类型都可以通过 typeof
来判断。
typeof null
的值为 object
,这是因为一个久远的 Bug,没有细究的必要,了解即可。如果想具体判断 null
类型的话直接 xxx === null
即可。
对于对象类型来说,typeof
只能具体判断函数的类型为 function
,其它均为 object
。
instanceof
instanceof
内部通过原型链的方式来判断是否为构建函数的实例,常用于判断具体的对象类型。
[] instanceof Array
复制代码
都说 instanceof
只能判断对象类型,其实这个说法是不准确的,我们是可以通过 hake 的方式得以实现,虽然不会有人这样去玩吧。
class CheckIsNumber {static [Symbol.hasInstance](number) {return typeof number === 'number'}
}// true
1 instanceof CheckIsNumber
复制代码
另外其实我们还可以直接通过构建函数来判断类型:
// true
[].constructor === Array
复制代码
Object.prototype.toString
前几种方式或多或少都存在一些缺陷,Object.prototype.toString
综合来看是最佳选择,能判断的类型最完整。
上图是一部分类型判断,更多的就不列举了,[object XXX]
中的 XXX
就是判断出来的类型。
isXXX API
同时还存在一些判断特定类型的 API,选了两个常见的:
常见考点
- JS 类型如何判断,有哪几种方式可用
instanceof
原理- 手写
instanceof
类型转换
类型转换分为两种情况,分别为强制转换及隐式转换。
强制转换
强制转换就是转成特定的类型:
Number(false) // -> 0
Number('1') // -> 1
Number('zb') // -> NaN
(1).toString() // '1'
复制代码
这部分是日常常用的内容,就不具体展开说了,主要记住强制转数字和布尔值的规则就行。
转布尔值规则:
undefined、null、false、NaN、''、0、-0
都转为false
。- 其他所有值都转为
true
,包括所有对象。
转数字规则:
true
为 1,false
为 0null
为 0,undefined
为NaN
,symbol
报错- 字符串看内容,如果是数字或者进制值就正常转,否则就
NaN
- 对象的规则隐式转换再讲
隐式转换
隐式转换规则是最烦的,其实笔者也记不住那么多内容。况且根据笔者目前收集到的最新面试题来说,这部分考题基本绝迹了,当然讲还是讲一下吧。
对象转基本类型:
- 调用
Symbol.toPrimitive
,转成功就结束 - 调用
valueOf
,转成功就结束 - 调用
toString
,转成功就结束 - 报错
四则运算符:
- 只有当加法运算时,其中一方是字符串类型,就会把另一个也转为字符串类型
- 其他运算只要其中一方是数字,那么另一方就转为数字
==
操作符
常见考点
如果这部分规则记不住也不碍事,确实有点繁琐,而且考的也越来越少了,拿一道以前常考的题目看看吧:
[] == ![] // -> ?
复制代码
this
this
是很多人会混淆的概念,但是其实他一点都不难,不要被那些长篇大论的文章吓住了(我其实也不知道为什么他们能写那么多字),你只需要记住几个规则就可以了。
普通函数
function foo() {console.log(this.a)
}
var a = 1
foo()var obj = {a: 2,foo: foo
}
obj.foo()// 以上情况就是看函数是被谁调用,那么 `this` 就是谁,没有被对象调用,`this` 就是 `window`// 以下情况是优先级最高的,`this` 只会绑定在 `c` 上,不会被任何方式修改 `this` 指向
var c = new foo()
c.a = 3
console.log(c.a)// 还有种就是利用 call,apply,bind 改变 this,这个优先级仅次于 new
复制代码
箭头函数
因为箭头函数没有 this
,所以一切妄图改变箭头函数 this
指向都是无效的。
箭头函数的 this
只取决于定义时的环境。比如如下代码中的 fn
箭头函数是在 windows
环境下定义的,无论如何调用,this
都指向 window
。
var a = 1
const fn = () => {console.log(this.a)
}
const obj = {fn,a: 2
}
obj.fn()
复制代码
常见考点
这里一般都是考 this
的指向问题,牢记上述的几个规则就够用了,比如下面这道题:
const a = {b: 2,foo: function () { console.log(this.b) }
}function b(foo) {// 输出什