1. call
call 方法可以指定函数内部 this 的指向,然后在所指定的作用域中,调用该函数。
let obj = {}
let f = function(){
return this
}
fn()===window //ture
f.call(obj)===obj //true
上面代码中,函数 f 运行时,this 指向全局环境;call 方法可以改变 this 的指向,指定 this 指向对象 obj,然后在此作用域中运行函数 f。
call 方法的第一个参数就是 this 所要指向的那个对象,后面的参数则是函数调用时所需的参数。如果参数为空、null 和 undefined,会默认传入全局对象。
//例1
let n = 11
let obj = {n: 22}
function fn(){
console.log(this.n)
}
fn.call() //11
fn.call(null) //11
fn.call(undefined) //11
fn.call(window) //11
fn.call(obj) //22
//例2
function add(a,b){
return a+b
}
add.call(add, 1, 2) //3
2. apply
apply 方法的作用和 call 类似,也是改变 this 的指向,然后调用该函数。区别是 apply 是接收一个数组作为函数的参数,即
func.apply(thisValue, [arg1, arg2, ...])
apply 方法的第一个参数也是 this 要指向的对象,如果设为 null 或 undefined,则等同于全局对象。第二个参数是一个数组,该数组中的成员依次作为参数,传入函数中。
function add(x, y){
console.log(x+y)
}
add.call(add, 1, 1) //2
add.apply(add, [1, 1]) //2
基于此,apply 方法可以有其他使用方式
//绑定回调函数对象
let obj = new Object()
obj.f = function(){
console.log(this===o)
}
let f = function(){
o.f.apply(o)
//o.f.call(o)
}
$('button').on('click', f)
上面代码中,点击按钮之后,控制台会显示 true。
3. bind
bind 方法用于将 this 绑定到某个对象上,然后返回一个新函数。
let counter = {
count: 0,
inc: function(){
this.count++
}
}
let fn1 = counter.inc.bind(counter)
fn1()
let obj = {
count: 10
}
let fn2 = counter.inc.bind(obj)
fn2()
counter.count //1
obj.count //11
上面代码中,counter.inc 被赋值给一个变量后,必须用 bind 方法将 inc() 内部的 this 绑定到一个对象上,否则会出错。
bind 方法还可以接受更多的参数,将这些参数绑定原函数的参数
function add(x, y){
return x+y
}
let plus1 = add.bind(add, 2)
plus1(33) //35
上面代码中,bind 方法除了绑定 this 对象,还将 add() 函数的第一个参数绑定成 2, 然后返回一个新函数 plus1,这个函数只需要接受一个参数 y即可运行。如果 bind 的第一个参数为 null 或 undefined,等于将 this 绑定到全局对象(浏览器中运行时指向 window)。