因为在 JavaScript 中 this 的多变和不确定性(变量提升和词法环境相关),因此JavaScript 提供了一些方式,在函数调用的时候, 指定 this

apply

  1. apply接受两个参数,第一个参数是this的指向,第二个参数是函数接受的参数,
  2. 以数组的形式传入,且当第一个参数为nullundefined的时候,默认指向window(在浏览器中),
  3. 使用apply方法改变this指向后原函数会立即执行,且此方法只是临时改变thi指向一次。
  4. var age = 20
  5. class Person {
  6. constructor(age){
  7. this.age = age
  8. this.age = 18
  9. }
  10. }
  11. function applySome(params) {
  12. console.log(this.age);
  13. }
  14. applySome() // 20 this指向 全局 window
  15. applySome.apply(new Person(), []) // 立即执行 18 this 指向传入的对象

call

  1. call方法的第一个参数也是this的指向,后面传入的是一个参数列表(注意和apply传参的区别)。
  2. 当一个参数为nullundefined的时候,表示指向window(在浏览器中),
  3. apply一样,call也只是临时改变一次this指向,并立即执行。
  4. // // apply
  5. var age = 20
  6. class Person {
  7. constructor(age){
  8. this.age = 18
  9. }
  10. }
  11. function applySome(params) {
  12. console.log(this.age);
  13. }
  14. applySome() // 20 this指向 全局 window
  15. applySome.call(new Person(), [20], [30]) // 立即执行 18 this 指向传入的对象

bind

  1. bind方法和call很相似,第一参数也是this的指向,
  2. 后面传入的也是一个参数列表(但是这个参数列表可以分多次传入,call则必须一次性传入所有参数),
  3. 但是它改变this指向后不会立即执行,而是返回一个永久改变this指向的函数。
  4. this.x = 9; // 在浏览器中,this 指向全局的 "window" 对象
  5. var module = {
  6. x: 81,
  7. getX: function() { return this.x; }
  8. };
  9. module.getX(); // 81
  10. var retrieveX = module.getX;
  11. retrieveX();
  12. // 返回 9 - 因为函数是在全局作用域中调用的
  13. // 创建一个新函数,把 'this' 绑定到 module 对象
  14. // 新手可能会将全局变量 x 与 module 的属性 x 混淆
  15. var boundGetX = retrieveX.bind(module);
  16. boundGetX(); // 81

apply,call,bind三者的区别

  • 三者都可以改变函数的this对象指向。
  • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window。
  • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入。
  • bind 是返回绑定this之后的函数,便于稍后调用;apply 、call 则是立即执行 。