this指向的四种情况

  • this 是在运行时进行绑定的,并不是在编写时绑定,它的上下文取决于函数调用时的各种条件。
  • this 的绑定和函数声明的位置没有任何关系,只取决于函数的调用方式。 
  • 当一个函数被调用时,会创建一个活动记录(有时候也称为执行上下文)。这个记录会包含函数在哪里被调用(调用栈)、函数的调用方式、传入的参数等信息。this 就是这个记录的一个属性,会在函数执行的过程中用到。

判断 this指向的四种情况

1. new

使用 new 来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。
  1.  创建(或者说构造)一个全新的对象。
  2.  这个新对象会被执行 [[Prototype]] 连接。
  3.  这个新对象会绑定到函数调用的 this
  4.  如果函数没有返回其他对象,那么 new 表达式中的函数调用会自动返回这个新对象。

简单说就是 通过new创建的对象, 函数this指向new出来的实例对象

2. callapply

function foo() { 
 console.log( this.a ); 
} 
var obj = { 
 a:2 
}; 
foo.call( obj ); // 2

简单说 call, apply 就是改变this指向的,但是会强制绑定到被调用的一个对象上,后面再用此方法,this还是指向第一次调用的那个对象.

举个例子 :

function foo() { 
 console.log( this.a ); 
}
var obj = { 
 a:2 
}; 
var bar = function() { 
 foo.call( obj ); 
}; 
bar(); // 2 
setTimeout( bar, 100 ); // 2 
// 硬绑定的 bar 不可能再修改它的 this 
bar.call( window ); // 2

3.  是否通过对象调用

function foo() { 
 console.log( this.a ); 
} 
var obj = { 
 a: 2, 
 foo: foo 
}; 
obj.foo(); // 2
简单说就是: 调用位置是否有上下文对象,或者说是否被某个对象拥有或者包含,不过这种说法可能会造成一些误导。
 

4. 默认绑定

function foo() { 
 console.log( this.a ); 
} 
var a = 2; 
foo(); // 2
如果都不是上面三种的话,就是默认绑定。如果在严格模式下,就绑定到 undefined,否则绑定到全局对象。
 

5. 箭头函数 (例外)

箭头函数并不是使用 function 关键字定义的,而是使用被称为“胖箭头”的操作符 => 定 义的。箭头函数不使用 this 的四种准规则,而是根据外层(函数或者全局)作用域来决定 this
 
function foo() { 
 // 返回一个箭头函数 
 return (a) => { 
 //this 继承自 foo() 
 console.log( this.a ); 
 }; 
} 

上面箭头函数代码可以看做   var self = this 这种方式实现; 

function foo() { 
 var self = this; 
 setTimeout( function(){ 
 console.log( self.a ); 
 }, 100 ); 
}

总结 :

  1. new 调用?绑定到新创建的对象。
  2. call 或者 apply(或者 bind)调用?绑定到指定的对象。
  3. 由上下文对象调用?绑定到那个上下文对象。
  4. 默认:在严格模式下绑定到 undefined,否则绑定到全局对象。
  5. ES6 中的箭头函数并不会使用四条标准的绑定规则,而是根据当前的词法作用域来决定
    this ,具体来说,箭头函数会继承外层函数调用的 this 绑定(无论 this 绑定到什么)。这
    其实和 ES6 之前代码中的 self = this 机制一样。

参考文献 : <你不知道的javascript>

你可能感兴趣的:(JavaScript,前端小知识,javascript)