通过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); obj.speak() obj.speak.apply(window) obj.speak.call(window) obj.speak.bind(window)()
|
机智的小伙伴们是不是一下子就发现了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
| function log() { console.log.apply(window, arguments) }
function log() { console.log.call(window, ...arguments) }
function log() { console.log.bind(window, ...arguments)() }
|
3.2 手动实现bind
1 2 3 4 5 6 7 8 9 10 11 12
| Function.prototype.myBind = function (context, ...preArgs) { return (...args) => { return this.call(context, ...preArgs, ...args) } } function log() { console.log.myBind(window, ...arguments)() } log(1) log(1, 2)
|