call、apply 和 bind

call()、apply()、bind() 都是用来重定义 this 这个对象的!

var obj1 = {
  username: "HuiTaiLang",
  fn: function() {
    concole.loh(this);     console.log(
this.username);   } } var obj2 = obj1.fn; obj2(); //undefined

我们想打印对象 obj2 里面的 username 却打印出来 undefined 是怎么回事呢?如果我们直接执行 obj2.fn()是可以的。

var obj1 = {
  username: "HuiTaiLang",
  fn: function() {
    console.log(this);     console.log(
this.username);   } } obj1.fn();   //HuiTaiLang

能够打印是因为,第一个打印里面的 this 指向全局window,第二个打印里面的 this 指向 obj1 。

虽然这种方法可以达到打印username目的,但是如果我们需要将对象保存到另外的一个变量中,那么就可以通过以下方法。

call

var obj1 = {  
  username: "HuiTaiLang",
  fn: function() {
    console.log(this)    
    console.log(this.username);  
  }
}
var obj2 = obj1.fn;
obj2.call(obj1);    // HuiTaiLang

通过在 call 方法,第一个参数就是要添加的 obj1环境中,简单来说,this就会指向那个对象。

call 方法除了第一个参数以外还可以添加多个参数,如下:

var obj1 = {  
  username: "HuiTaiLang",
  fn: function(num1, num2) {
    console.log(num1 + num2); 
    console.log(this.username);  
  }
}
var obj2 = obj1.fn;
obj2.call(obj1, 2, 3);  // 5

apply

apply方法和call方法有些相似,它也可以改变this的指向。

var obj1 = {  
  username: "HuiTaiLang",
  fn: function() {
    console.log(this.username);  
  }
}
var obj2 = obj1.fn;
obj2.apply(obj1);   // HuiTaiLang

同样apply也可以有多个参数,但是不同的是,第二个参数必须是一个数组,如下:

var obj1 = {  
  username: "HuiTaiLang",
  fn: function(num1, num2) {
    console.log(num1 + num2); 
    console.log(this.username);  
  }
}
var obj2 = obj1.fn;
obj2.apply(obj1, [2, 3]);   // 5

注意:如果call和apply的第一个参数写的是null,那么this指向的是window对象。

var obj1 = {  
  username: "HuiTaiLang",
  fn: function() {
    console.log(this);  
  }
}
var obj2 = obj1.fn;
var obj3 = obj1.fn;
obj2.call(null);    // window
obj3.apply(null);   // window

bind

bind和call、apply方法不同,实际上bind方法返回的是一个修改过后的函数。

var obj1 = {  
  username: "HuiTaiLang",
  fn: function() {
    console.log(this.username);  
  }
}
var obj2 = obj1.fn;
obj2.bind(obj1);
var newFn = obj2.bind(obj1); console.log(newFn); newFn();

我们会发现 bind 并没有被打印,而我们打印 newFn 打印出的是一个函数,并且可以正常执行。

同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。

var obj1 = {  
  username: "HuiTaiLang",
  fn: function(num1, num2) {
    console.log(num1 + num2);
    console.log(this.username);  
  }
}
var obj2 = obj1.fn;
var newFn1 = obj2.bind(obj1, 2, 3);
var newFn2 = obj2.bind(obj1);
newFn1();
newFn1(2, 3);

 总结:

call 、bind 、apply 都可以用来改变上下文中的 this。这三个函数的第一个参数都是 this 的指向对象,后面的参数:

  • call 的参数是直接放进去的,后面的参数全都用逗号分隔。
  • apply 的所有参数,都必须放在一个数组里面传进去。
  • bind 除了返回是函数以外,它的参数和 call 一样。

当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!

 

posted @ 2021-10-01 11:04  辉太狼`  阅读(28)  评论(0编辑  收藏  举报