什么是 this ?
在说 call、apply 和 bind 之前,我们先来看看 Javascript 中的 this 是什么。
先来看一段代码 ⬇️ ⬇️ ⬇️
上面代码中,虽然 obj.fn 和 b 指向同一个函数,但是执行结果不一样。这种差异的原因,就在于函数内使用了 this 关键字。 this 指的是函数运行时所在的环境。
在内存图中,变量 obj 的值指向了一个地址,这个地址里保存了 a 和 fn ,而由于 fn 是一个函数,那么 fn 的值也是一个地址,在 fn 指向这个地址中保存了 fn 这个函数的函数体,所以这个函数是一个单独的值,那么他就可以在不同的环境中执行。

this 就指的是函数运行时的环境。
- 所以当运行
obj.fn()时,fn()的运行环境是obj,所以这时候this.a就是obj.a; - 当运行
b()时,b()的运行环境是window,所以这时候this.a就是window.a。
由此得出,
this的值就是.前面的环境。
call、apply 和 bind
了解了 this 之后,就可以说说 call、apply 和 bind 了。
call
MDN:
call()允许为不同的对象分配和调用属于一个对象的函数/方法。call()提供新的this值给当前调用的函数/方法。你可以使用call来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。
通俗点讲就是,call 可以改变调用函数时的 this 值。以便我们可以在其他的地方调用同一个方法而不用再写一次该方法。
了解了概念,那就看看怎么用吧。还是上面的代码,我们试着用 call 来调用它。
在调用 b() 的时候,使用 call 改变了 this 的指向,让他仍然指向 obj ,于是运行 b() 的结果没我们就得到了和 obj.fn() 一样的结果了。
总结一下 call 的用法:
|
|
call的第一个参数是你要指定的this,之后的参数就是函数自身的参数。
apply
call()方法的作用和apply()方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组。
直接来看用法吧:
|
|
apply的第一个参数是你要指定的this,之后的数组就是函数自身的参数组成的数组。
bind
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被指定为bind()的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
bind() 返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。
还是上面的代码:
我们让 c 等于 fn.bind(obj) 之后我们发现,使用 call 指定 c() 的 this 为任意对象,都不会改变运行结果。这就是因为bind() 返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。
他返回的是一个新函数, this 是创建时候指定的 this 值,并且不会被 call apply 等改变。
与 call 和 apply 不同的是,上面两个在指定了 this 之后立即执行,而 bind 返回的是一个新的函数,在改变了函数的 this 的同时不会执行函数,可以在之后需要的时候再调用。
以上就是 this 、call 、 apply 和 bind 的简单讲解了。