call、apply、bind

101 阅读2分钟

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 所要指向的那个对象,后面的参数则是函数调用时所需的参数。如果参数为空、nullundefined,会默认传入全局对象。

//例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 要指向的对象,如果设为 nullundefined,则等同于全局对象。第二个参数是一个数组,该数组中的成员依次作为参数,传入函数中。

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 的第一个参数为 nullundefined,等于将 this 绑定到全局对象(浏览器中运行时指向 window)。