---
sidebarDepth: 4
pageClass: custom-code-highlight
---
# 第五部分:高频考点
> [如果您觉得有帮助,可以打赏我](https://upload-images.jianshu.io/upload_images/1480597-1f247397539045cc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) ![](![](https://upload-images.jianshu.io/upload_images/1480597-1f247397539045cc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240))
> [关注微信公众号获取更多面试题:@静观流叶](https://upload-images.jianshu.io/upload_images/1480597-933c7247ddac5ed4.png) ![](![](https://upload-images.jianshu.io/upload_images/1480597-933c7247ddac5ed4.png))
> 来自掘金小册笔记
## 1 typeof类型判断
> `typeof` 是否能正确判断类型?`instanceof` 能正确判断对象的原理是什么
- `typeof` 对于原始类型来说,除了 `null` 都可以显示正确的类型
```js
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
```
> `typeof` 对于对象来说,除了函数都会显示 `object`,所以说 `typeof` 并不能准确判断变量到底是什么类型
```js
typeof [] // 'object'
typeof {} // 'object'
typeof console.log // 'function'
```
> 如果我们想判断一个对象的正确类型,这时候可以考虑使用 `instanceof`,因为内部机制是通过原型链来判断的
```js
const Person = function() {}
const p1 = new Person()
p1 instanceof Person // true
var str = 'hello world'
str instanceof String // false
var str1 = new String('hello world')
str1 instanceof String // true
```
> 对于原始类型来说,你想直接通过 `instanceof `来判断类型是不行的
## 2 类型转换
> 首先我们要知道,在 `JS` 中类型转换只有三种情况,分别是:
- 转换为布尔值
- 转换为数字
- 转换为字符串
![image.png](https://upload-images.jianshu.io/upload_images/1480597-c1ede6d7eb711a22.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
**转Boolean**
> 在条件判断时,除了 `undefined`,` null`, `false`, `NaN`, `''`, `0`, `-0`,其他所有值都转为 `true`,包括所有对象
**对象转原始类型**
> 对象在转换类型的时候,会调用内置的 `[[ToPrimitive]]` 函数,对于该函数来说,算法逻辑一般来说如下
- 如果已经是原始类型了,那就不需要转换了
- 调用 `x.valueOf()`,如果转换为基础类型,就返回转换的值
- 调用 `x.toString()`,如果转换为基础类型,就返回转换的值
- 如果都没有返回原始类型,就会报错
> 当然你也可以重写 `Symbol.toPrimitive `,该方法在转原始类型时调用优先级最高。
```js
let a = {
valueOf() {
return 0
},
toString() {
return '1'
},
[Symbol.toPrimitive]() {
return 2
}
}
1 + a // => 3
```
**四则运算符**
> 它有以下几个特点:
- 运算中其中一方为字符串,那么就会把另一方也转换为字符串
- 如果一方不是字符串或者数字,那么会将它转换为数字或者字符串
```js
1 + '1' // '11'
true + true // 2
4 + [1,2,3] // "41,2,3"
```
- 对于第一行代码来说,触发特点一,所以将数字 `1` 转换为字符串,得到结果 `'11'`
- 对于第二行代码来说,触发特点二,所以将 `true` 转为数字 `1`
- 对于第三行代码来说,触发特点二,所以将数组通过 `toString `转为字符串 `1,2,3`,得到结果 `41,2,3`
> 另外对于加法还需要注意这个表达式 `'a' + + 'b'`
```
'a' + + 'b' // -> "aNaN"
```
- 因为 `+ 'b'` 等于 `NaN`,所以结果为 `"aNaN"`,你可能也会在一些代码中看到过 `+ '1' `的形式来快速获取 `number` 类型。
- 那么对于除了加法的运算符来说,只要其中一方是数字,那么另一方就会被转为数字
```js
4 * '3' // 12
4 * [] // 0
4 * [1, 2] // NaN
```
**比较运算符**
- 如果是对象,就通过 `toPrimitive` 转换对象
- 如果是字符串,就通过 `unicode` 字符索引来比较
```js
let a = {
valueOf() {
return 0
},
toString() {
return '1'
}
}
a > -1 // true
```
> 在以上代码中,因为 `a` 是对象,所以会通过 `valueOf` 转换为原始类型再比较值。
## 3 This
> 我们先来看几个函数调用的场景
```js
function foo() {
console.log(this.a)
}
var a = 1
foo()
const obj = {
a: 2,
foo: foo
}
obj.foo()
const c = new foo()
```
- 对于直接调用 `foo` 来说,不管 `foo` 函数被放在了什么地方,`this` 一定是` window`
- 对于 `obj.foo()` 来说,我们只需要记住,谁调用了函数,谁就是 `this`,所以在这个场景下 `foo` 函数中的 `this` 就是 `obj` 对象
- 对于 `new` 的方式来说,`this` 被永远绑定在了 `c` 上面,不会被任何方式改变 `this`
> 说完了以上几种情况,其实很多代码中的 `this` 应该就没什么问题了,下面让我们看看箭头函数中的 `this`
```js
function a() {
return () => {
return () => {
console.log(this)
}
}
}
console.log(a()()())
```
- 首先箭头函数其实是没有 `this` 的,箭头函数中的 `this` 只取决包裹箭头函数的第一个普通函数的 `this`。在这个例子中,因为包裹箭头函数的第一个普通函数是 `a`,所以此时的 `this` 是 `window`。另外对箭头函数使用 `bind `这类函数是无效的。
- 最后种情况也就是 `bind` 这些改变上下文的 `API` 了,对于这些函数来说,`this` 取决于第一个参数,如果第一个参数为空,那么就是 `window`。
- 那么说到 `bind`,不知道大家是否考虑过,如果对一个函数进行多次 `bind`,那么上下文会是什么呢?
```js
let a = {}
let fn = function () { console.log(this) }
fn.bind().bind(a)() // => ?
```
> 如果你认为输出结果是 `a`,那么你就错了,其实我们可以把上述代码转换成另一种形式
```js
// fn.bind().bind(a) 等于
let fn2 = function fn1() {
return function() {
return fn.apply()
}.apply(a)
}
fn2()
```
> 可以从上述代码中发现,不管我们给函数 `bind` 几次,`fn` 中的 `this` 永远由第一次 `bind` 决定,所以结果永远是 `window`
```js
let a = { name: 'poetries' }
function foo() {
console.log(this.name)
}
foo.bind(a)() // => 'poetries'
```
> 以上就是 `this` 的规则了,但是可能会发生多个规则同时出现的情况,这时候不同的规则之间会根据优先级最高的来决定 `this` 最终指向哪里。
> 首先,`new` 的方式优先级最高,接下来是 `bind` 这些函数,然后是 `obj.foo()` 这种调用方式,最后是 `foo` 这种调用方式,同时,箭头函数的 `this` 一旦被绑定,就不会再被任何方式所改变。
![image.png](https://upload-images.jianshu.io/upload_images/1480597-ce6e82dfdc1b3415.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 4 == 和 === 有什么区别
> 对于 `==` 来说,如果对比双方的类型不一样的话,就会进行类型转换
**假如我们需要对比 x 和 y 是否相同,就会进行如下判断流程**
1. 首先会判断两者类型是否相同。相同的话就是比大小了
2. 类型不相同的话,那么就会进行类型转换
3. 会先判断是否在对比 `null` 和 `undefined`,是的话就会返回 `true`
4. 判断两者类型是否为 `string` 和 `number`,是的话就会将字符串转换为 `number`
```
1 == '1'
↓
1 == 1
```
5. 判断其中一方是否为 `boolean`,是的话就会把 `boolean` 转为 `number` 再进行判断
```
'1' == true
↓
'1' == 1
↓
1 == 1
```
6. 判断其中一方是否为 `object` 且另一方为 `string`、`number` 或者 `symbol`,是的话就会把 `object` 转为原始类型再进行判断
```
'1' == { name: 'yck' }
↓
'1' == '[object Object]'
```
![image.png](https://upload-images.jianshu.io/upload_images/1480597-88daf8ffd440c0dd.png?imageMogr2/auto-ori
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
frontinterview前端面试题持续更新中...基础,进阶,react,vue,node,小程序,前端算法,安全,常考面试题.zip (96个子文件)
frontend-interview-dfe-master
vue
readme.md 16B
base.md 14KB
advance.md 231B
.DS_Store 6KB
simply
README.md 22KB
guide
markdown.md 961B
README.md 965B
world.md 958B
improve
README.md 35KB
review
README.md 32KB
company
a360-01.md 8KB
alibaba-test-blow.md 3KB
201708alibaba.md 1KB
list-oop-alibaba.md 1KB
toutiao-reamd.md 4KB
list-oop-ace.md 1KB
net-ease-01.md 7KB
JSON-stringify-alibab.md 1KB
example.md 2KB
alibaba-knife.md 875B
README.md 78B
arithmetic
readme.md 30B
readme.md 2KB
advance
frame.md 21KB
generator.md 2KB
answer.md 9KB
extends.md 2KB
summary.md 142KB
browser.md 15KB
depth-copy.md 2KB
this.md 973B
closure.md 2KB
performance.md 5KB
mvvm.md 6KB
javascript.md 33KB
event-loop.md 6KB
proxy.md 901B
example.md 538B
common.md 4KB
README.md 86B
promise.md 6KB
package.json 834B
base
basic-config.md 2KB
deploy.md 5KB
guide
css.md 30KB
cookie.md 745B
ajax.md 892B
getting-started.md 2KB
meta-viewport.md 3KB
css.md 30KB
ES6.md 23KB
README copy.md 5KB
html-dom.md 1KB
Handwritten-code.md 9KB
Git.md 187B
html.md 15KB
directory-structure.md 3KB
dom-event.md 8KB
markdown-slot.md 3KB
i18n.md 3KB
cookie.md 745B
permalinks.md 2KB
img
2019-03-12-10-46-13.png 260KB
hello.md 986B
Front-end-frame-relative.md 12KB
HTTP协议.md 6KB
using-vue.md 7KB
global-computed.md 1KB
css-bfc.md 10KB
comprehensive.md 2KB
frontmatter.md 2KB
dataBase.md 492B
markdown.md 7KB
computer-basic-knowledge.md 342B
ajax.md 913B
README.md 165KB
data-structure.md 2KB
cross-domain.md 3KB
HTTP.md 10KB
assets.md 2KB
excellent
README.md 234KB
algorithm
sort.md 5KB
search.md 3KB
README.md 237B
computed-base
README.md 49KB
.gitignore 135B
node
base.md 7KB
README.md 965B
print
depth-copy.md 2KB
closure.md 2KB
README.md 165KB
react
reactHigher.md 8KB
readme.md 15KB
keys-use.md 627B
base.md 15KB
advance.md 124B
共 96 条
- 1
资源评论
天天501
- 粉丝: 588
- 资源: 4666
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功