# JavaScript相关知识点集锦(四):this 、箭头函数、以及apply、call与bind
本文分为两部分:
- 正确判断
this- 手写
apply、call、bind
# 正确判断 this
this 是个容易让人混淆的概念,但只要我们理清了思路就会很容易理解。
对于单个规则来说,我们可以按照下面的流程来进行判断:
- 首先,判断函数类型
- 若是箭头函数,
this就是包裹箭头函数的第一个普通函数的this - 若是
apply、call、bind,this是第一个参数 - 普通函数的话,要判断函数是如何被调用的
new的方式,this被固化在实例上面- 除了
new方式以外,判断函数是直接调用(foo())还是通过对象调用 (obj.foo())foo()方式,this为windowobj.foo()方式,this为obj
- 若是箭头函数,

通过这个流程,我们可以准确判断 this。当然,如果我们向改变 this,就可以采用以下方式:
- 使用箭头函数
- 使用
apply、call、bind方法 - 当然,构造函数也可以改变
this,通过对象调用也行
# 手写 apply、call、bind
关于 apply、call、bind,都可以改变 this 的指向,但稍稍有些不同。
apply和call的区别 其实apply和call基本类似,他们的区别主要是传参不同call的语法: fun.call(thisArg[, arg1[, arg2[, ...]]])apply的语法: fun.apply(thisArg, [argsArray]) 所以apply和call的区别是call方法接受的是若干个参数列表,而apply接收的是一个包含多个参数的数组。bind和apply、call区别bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。 从这句话,我们可以看出,
bind是创建一个新的函数,需要我们手动去执行。 这是bind与apply、call的主要区别。- 手写
apply、call、bind
Function.prototype.myCall = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
const args = [...arguments].slice(1)
const result = context.fn(...args)
delete context.fn
return result
}
Function.prototype.myApply = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
context = context || window
context.fn = this
let result
if (arguments[1]) {
result = context.fn(...arguments[1])
} else {
result = context.fn()
}
return result
}
Function.prototype.myBind = function(context) {
if (typeof this !== 'function') {
throw new TypeError('Error')
}
const _this = this
const args = [...arguments].slice(1)
return function F() {
if (this instanceof F) {
return new _this(...args, ...arguments)
}
return _this.apply(context, args.concat(...arguments))
}
}
var obj = {
name: '这是'
}
function printName (fname, lname) {
console.log(this)
console.log(`${this.name} ${fname}${lname}`)
}
printName('liao', 'rui')
printName.myCall(obj, 'liao', 'rui')
printName.myApply(obj, ['liao', 'rui'])
printName.myBind(obj, 'liao', 'rui')()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
本文完, 感谢阅读。