JS 中的this指向问题和call、apply、bind的区别

this的指向问题

  • 一般情况下this对象指向调用函数的对象,全局环境中执行函数this对象指向window。
function a(){   
  console.log(this);   //输出函数a中的this对象
}
function b(){};
var c={name:"call"};    //定义对象c  
var c = { 
 getFunc:function(){
   return function(){ 
  		console.log(this) 
   } 
 } 
}
var cFun = c.getFunc(); 
cFun()//Window 这是因为在全局环境下执行的函数
  • 在call和apply函数中this指向的是指定的对象,如果指定的对象为undefined或者null,那this对象指向window,如果指定的对象为空this也是指向的window,如果指向的对象是字符串,那this指向的就是String
var d = { 
 	getThis:function(){ 
 		console.log(this) 
 	} 
 } 
 var e = { 
 	name:'e'//(给e写个`name`属性只是因为觉得孤零零的太难看了~~) 
 } 
 d.getThis.call(e);   //这句话就相当于说把对象d中的上下文环境换成了对象e
 d.getThis.call(66);  //Number
 d.getThis.call('wan');  //String
 d.getThis.call();  //Window
 d.getThis.call(true);  //Boolean
  • 如果在箭头函数中,this对象等同于外层代码中的this
var f = {
 	getThis: ()=>{ 
 		console.log(this) 
 	},
 	getThis2: function(){
 		console.log(this);
 	} 
 } 
 f.getThis(); //Window
 f.getThis2();  //f

call、apply、bind的区别

  • call的基本用法
    • 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]])
    • 定义:调用一个对象的一个方法,以另一个对象替换当前对象。
    • call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
    • thisObj的取值有以下4种情况:
      • 不传,或者传null,undefined, 函数中的this指向window对象
      • 传递另一个函数的函数名,函数中的this指向这个函数的引用
      • 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean
      • 传递一个对象,函数中的this指向这个对象
function a(){   
  console.log(this);   //输出函数a中的this对象
}       
function b(){}       
var c={name:"call"};    //定义对象c  
a.call();   //window
a.call(null);   //window
a.call(undefined);   //window
a.call(1);   //Number
a.call('');   //String
a.call(true);   //Boolean
a.call(b);   //function b(){}
a.call(c);   //Object
  • apply的基本用法
    • 语法:**apply([thisObj[,argArray]]) **
    • 定义:应用某一对象的一个方法,用另一个对象替换当前对象。
    • 如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。
      如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。
function class1(args1,args2){       
  this.name=function(){      
   console.log(args,args);      
  }     
}     
function class2(){    
  var args1="1";
  var args2="2";
  class1.call(this,args1,args2);  
  /*或*/
  class1.apply(this,[args1,args2]);
}
var c=new class2();   
c.name();  //1,2
  • bind的基本用法
    • bind是在EcmaScript5中扩展的方法(IE6,7,8不支持)
    • bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。
    • bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数
      var bar = function(){
      console.log(this.x);
      }
      var foo = {
      x:3
      }
      bar(); // undefined
      var func = bar.bind(foo);
      func(); // 3
    
  • call、apply、bind三者的区别
    • 三者都是来改变函数的this对象的指向的
    • 三者的第一个参数都是this要指向的对象,也就是要指定的上下文
    • 三者都可以利用后续参数传参
    • bind是返回对应函数,便于稍后调用,call、apply是立即调用
    • call和apply作用是完全一样的,只是接收参数的方式不一样,call需要把参数按顺序传递进去,而apply则是把参数放在数组里。
      var obj = {
          x: 81,
      };
      var foo = {
          getX: function() {
              return this.x;
          }
      }
      console.log(foo.getX.bind(obj)());  //81
      console.log(foo.getX.call(obj));    //81
      console.log(foo.getX.apply(obj));   //81
      三个输出的都是81,但是注意看使用 bind() 方法的,他后面多了对括号。
    

参考文章:https://www.cnblogs.com/libin-1/p/6069031.html

原文地址:https://www.cnblogs.com/wancheng7/p/8405856.html