apply、call、bind的用法以及区别

通过call()函数或者apply()函数可以改变函数执行的主体,使得某些不具有特定函数的对象可以直接调用该特定函数。

先看一段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
var name = '呆呆', age = 17;
var obj = {
name: '校长',
objage: this.age,
speak: function () {
console.log(this.name + '年龄' + this.age)
}
}
console.log(obj.objage); // 17
obj.speak() // 校长年龄undefined
obj.speak.apply(window) // 呆呆年龄17
obj.speak.call(window) // 呆呆年龄17
obj.speak.bind(window)() // 呆呆年龄17

机智的小伙伴们是不是一下子就发现了apply、call、bind的用途,改变函数体内 this 的指向

1、 apply、call、bind的使用具体方法

1.1 apply

apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。

1
2
3
4
5
6
7
8
9
var name = '呆呆', age = 17;
var obj = {
name: '校长',
objage: this.age,
speak: function (sex, work) {
console.log('姓名' + this.name + '年龄' + this.age + '性别' + sex + '工作' + work)
}
}
obj.speak.apply(window, ['男', '程序员'])

1.2 call

call 方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。

1
2
3
4
5
6
7
8
9
var name = '呆呆', age = 17;
var obj = {
name: '校长',
objage: this.age,
speak: function (sex, work) {
console.log('姓名' + this.name + '年龄' + this.age + '性别' + sex + '工作' + work)
}
}
obj.speak.call(window, '男', '程序员')

1.3 bind

bind 方法第一个参数仍然是作为函数上下文的对象,后面传入的也是一个参数列表。

1
2
3
4
5
6
7
8
9
var name = '呆呆', age = 17;
var obj = {
name: '校长',
objage: this.age,
speak: function (sex, work) {
console.log('姓名' + this.name + '年龄' + this.age + '性别' + sex + '工作' + work)
}
}
obj.speak.bind(window, '男', '程序员')()

2、 区别

1.apply第二个参数是数组,而call和bind是参数列表

2.bind 是返回对应函数,apply和call则是立即调用

3、 拓展

3.1 定义一个 log 方法,让它可以代理 console.log 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 使用apply
function log() {
console.log.apply(window, arguments)
}

// 使用call
function log() {
console.log.call(window, ...arguments)
}

// 使用bind
function log() {
console.log.bind(window, ...arguments)()
}

3.2 手动实现bind

1
2
3
4
5
6
7
8
9
10
11
12
// es6版本的实现
Function.prototype.myBind = function (context, ...preArgs) {
return (...args) => {
// 箭头函数本身没有作用域,它的作用域即父作用域
return this.call(context, ...preArgs, ...args)
}
}
function log() {
console.log.myBind(window, ...arguments)()
}
log(1) // 1
log(1, 2) // 1 2

apply、call、bind的用法以及区别
https://xypecho.github.io/2020/02/27/apply、call、bind的用法以及区别/
作者
很青的青蛙
发布于
2020年2月27日
许可协议